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 : playerclasses . inc
* Type : Core
* Description : Provides functions for managing classes .
*
* 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
*
* ============================================================================
*/
/*
Ideas for immunity modes for humans :
- Zombies have to stab x times to infect .
- Zombies have to hurt humans so they loose hp . When the hp reach zero ( or
below ) they turn into zombies .
- Fully imune to all damage . Can ' t take or give damage . Sould only be used
2009-08-13 18:31:21 +02:00
on admin mode classes .
2009-04-06 03:20:13 +02:00
TODO : Make class attributes for for changing model render mode and colors .
TODO : Make class attributes for fancy effects , like a glow ( if possible ) .
TODO : Make immunity settings suitable for both teams , or certain zombie -
only / human - only settings .
*/
/**
2011-07-10 13:37:00 +02:00
* Total number of classes that can be stored in each cache .
2009-04-06 03:20:13 +02:00
*/
2011-07-10 13:37:00 +02:00
#define ZR_CLASS_MAX 64
2009-04-06 03:20:13 +02:00
/**
* @ section Class cache types . Specifies what data array to use .
*/
#define ZR_CLASS_CACHE_ORIGINAL 0 /** Points ClassData array. A cache that is never changed after loading. */
#define ZR_CLASS_CACHE_MODIFIED 1 /** Points to ClassDataCache array. Modified by admins or overrides. */
#define ZR_CLASS_CACHE_PLAYER 2 /** Points to ClassPlayerCache array. Current player attributes. */
/**
* @ endsection
*/
/**
* Number of available class teams .
*/
#define ZR_CLASS_TEAMCOUNT 3
/**
* @ section Available class teams . The admin team is optional and not required
* in class configs .
*/
#define ZR_CLASS_TEAM_ZOMBIES 0
#define ZR_CLASS_TEAM_HUMANS 1
#define ZR_CLASS_TEAM_ADMINS 2 /** Note: Will set you in a special mode where you don't really participates in the game, but just walk around. */
/**
* @ endsection
*/
/**
* @ section Damage immunity modes . The mode effects will vary depending on the
* class team .
*/
#define ZR_CLASS_IMMUNITY_DISABLED 0 /** No immunity. */
#define ZR_CLASS_IMMUNITY_CONSTANT 1 /** Always imune. Should only be used in special cases like on admin classes. */
#define ZR_CLASS_IMMUNITY_TIMED 2 /** Imune to damage for n seconds. The time is specified in a class as immunity amount. */
/**
* @ endsection
*/
2009-06-22 01:09:51 +02:00
/**
* @ section Flags for special classes .
*/
#define ZR_CLASS_FLAG_ADMIN_ONLY (1<<0) /** Class is usable by admins only. */
#define ZR_CLASS_FLAG_MOTHER_ZOMBIE (1<<1) /** Class is usable by mother zombies only. */
/** A combination of special class flags. Used to exclude special classes. */
#define ZR_CLASS_SPECIALFLAGS ZR_CLASS_FLAG_ADMIN_ONLY + ZR_CLASS_FLAG_MOTHER_ZOMBIE
/**
* @ endsection
*/
2009-04-06 03:20:13 +02:00
/**
* @ section Overall default class settings . Since this is a zombie plugin the
* default values represent a zombie .
*/
2009-08-15 02:58:49 +02:00
#define ZR_CLASS_DEFAULT_ENABLED "yes"
2009-04-06 03:20:13 +02:00
#define ZR_CLASS_DEFAULT_TEAM ZR_CLASS_TEAM_ZOMBIES
2009-08-15 02:58:49 +02:00
#define ZR_CLASS_DEFAULT_TEAM_DEFAULT "yes"
2009-06-22 01:09:51 +02:00
#define ZR_CLASS_DEFAULT_FLAGS 0
2009-08-13 18:31:21 +02:00
#define ZR_CLASS_DEFAULT_GROUP ""
2009-04-06 03:20:13 +02:00
#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"
#define ZR_CLASS_DEFAULT_ALPHA_INITIAL 255
#define ZR_CLASS_DEFAULT_ALPHA_DAMAGED 255
#define ZR_CLASS_DEFAULT_ALPHA_DAMAGE 0
#define ZR_CLASS_DEFAULT_OVERLAY_PATH "overlays/zr/zvision"
2009-08-15 02:58:49 +02:00
#define ZR_CLASS_DEFAULT_NVGS "no"
2009-04-06 03:20:13 +02:00
#define ZR_CLASS_DEFAULT_FOV 90
2009-09-27 23:45:17 +02:00
#define ZR_CLASS_DEFAULT_HAS_NAPALM "no"
2009-04-06 03:20:13 +02:00
#define ZR_CLASS_DEFAULT_NAPALM_TIME 10.0
#define ZR_CLASS_DEFAULT_IMMUNITY_MODE ZR_CLASS_IMMUNITY_DISABLED
#define ZR_CLASS_DEFAULT_IMMUNITY_AMOUNT 0.0
2009-09-27 23:45:17 +02:00
#define ZR_CLASS_DEFAULT_NO_FALL_DAMAGE "yes"
2009-04-06 03:20:13 +02:00
#define ZR_CLASS_DEFAULT_HEALTH 6000
#define ZR_CLASS_DEFAULT_HEALTH_REGEN_INTERVAL 0.0
#define ZR_CLASS_DEFAULT_HEALTH_REGEN_AMOUNT 2
#define ZR_CLASS_DEFAULT_HEALTH_INFECT_GAIN 800
#define ZR_CLASS_DEFAULT_KILL_BONUS 2
2010-07-04 17:58:27 +02:00
#define ZR_CLASS_DEFAULT_SPEED 0.0
2009-04-06 03:20:13 +02:00
#define ZR_CLASS_DEFAULT_KNOCKBACK 2.0
#define ZR_CLASS_DEFAULT_JUMP_HEIGHT 10.0
#define ZR_CLASS_DEFAULT_JUMP_DISTANCE 0.2
/**
* @ endsection
*/
2009-04-25 14:19:14 +02:00
/**
* @ section Attribute limit values . Used when validating .
*/
2009-06-14 19:10:30 +02:00
#define ZR_CLASS_TEAM_MIN 0
#define ZR_CLASS_TEAM_MAX 2
2009-06-22 01:09:51 +02:00
#define ZR_CLASS_FLAGS_MIN 0
#define ZR_CLASS_FLAGS_MAX 3
2009-04-25 14:19:14 +02:00
#define ZR_CLASS_NAME_MIN 1
#define ZR_CLASS_DESCRIPTION_MIN 1
/** Model path is checked for existance. */
#define ZR_CLASS_ALPHA_INITIAL_MIN 0
#define ZR_CLASS_ALPHA_INITIAL_MAX 255
#define ZR_CLASS_ALPHA_DAMAGED_MIN 0
#define ZR_CLASS_ALPHA_DAMAGED_MAX 255
#define ZR_CLASS_ALPHA_DAMAGE_MIN 0
2009-05-01 11:34:07 +02:00
#define ZR_CLASS_ALPHA_DAMAGE_MAX 20000
2009-04-25 14:19:14 +02:00
/** Overlay path is optional, and file is checked for existance if specified. */
#define ZR_CLASS_FOV_MIN 15
#define ZR_CLASS_FOV_MAX 165
#define ZR_CLASS_NAPALM_TIME_MIN 0.0
#define ZR_CLASS_NAPALM_TIME_MAX 600.0
#define ZR_CLASS_HEALTH_MIN 1
2009-05-01 11:34:07 +02:00
#define ZR_CLASS_HEALTH_MAX 20000
2009-06-22 01:09:51 +02:00
#define ZR_CLASS_REGEN_INTERVAL_MIN 0.0
#define ZR_CLASS_REGEN_INTERVAL_MAX 900.0
#define ZR_CLASS_REGEN_AMOUNT_MIN 0
#define ZR_CLASS_REGEN_AMOUNT_MAX 10000
2009-04-25 14:19:14 +02:00
#define ZR_CLASS_HEALTH_INFECT_GAIN_MIN 0
2009-05-01 11:34:07 +02:00
#define ZR_CLASS_HEALTH_INFECT_GAIN_MAX 20000
2009-04-25 14:19:14 +02:00
#define ZR_CLASS_KILL_BONUS_MIN 0
#define ZR_CLASS_KILL_BONUS_MAX 16
2010-07-04 17:58:27 +02:00
#define ZR_CLASS_SPEED_LMV_MIN 10.0
#define ZR_CLASS_SPEED_LMV_MAX 2000.0
#define ZR_CLASS_SPEED_PROP_MIN -200.0
2010-07-25 20:44:47 +02:00
#define ZR_CLASS_SPEED_PROP_MAX 1750.0
2009-05-01 11:34:07 +02:00
#define ZR_CLASS_KNOCKBACK_MIN -30.0
#define ZR_CLASS_KNOCKBACK_MAX 30.0
2009-09-27 23:45:17 +02:00
#define ZR_CLASS_KNOCKBACK_IGNORE -31.0 /** Used by class editor volumetric feature. */
2009-07-07 03:11:27 +02:00
#define ZR_CLASS_JUMP_HEIGHT_MIN 0.0
#define ZR_CLASS_JUMP_HEIGHT_MAX 5.0
#define ZR_CLASS_JUMP_DISTANCE_MIN 0.0
2009-05-10 18:49:47 +02:00
#define ZR_CLASS_JUMP_DISTANCE_MAX 5.0
2009-04-25 14:19:14 +02:00
/**
* @ endsection
*/
2009-04-07 04:44:37 +02:00
/**
2009-06-22 01:09:51 +02:00
* @ 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)
2009-08-13 18:31:21 +02:00
#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_ALPHA_INITIAL (1<<8)
#define ZR_CLASS_ALPHA_DAMAGED (1<<9)
#define ZR_CLASS_ALPHA_DAMAGE (1<<10)
#define ZR_CLASS_OVERLAY_PATH (1<<11)
#define ZR_CLASS_NVGS (1<<12)
#define ZR_CLASS_FOV (1<<13)
#define ZR_CLASS_HAS_NAPALM (1<<14)
#define ZR_CLASS_NAPALM_TIME (1<<15)
#define ZR_CLASS_IMMUNITY_MODE (1<<16)
#define ZR_CLASS_IMMUNITY_AMOUNT (1<<17)
#define ZR_CLASS_NO_FALL_DAMAGE (1<<18)
#define ZR_CLASS_HEALTH (1<<19)
#define ZR_CLASS_HEALTH_REGEN_INTERVAL (1<<20)
#define ZR_CLASS_HEALTH_REGEN_AMOUNT (1<<21)
#define ZR_CLASS_HEALTH_INFECT_GAIN (1<<22)
#define ZR_CLASS_KILL_BONUS (1<<23)
#define ZR_CLASS_SPEED (1<<24)
#define ZR_CLASS_KNOCKBACK (1<<25)
#define ZR_CLASS_JUMP_HEIGHT (1<<26)
#define ZR_CLASS_JUMP_DISTANCE (1<<27)
2009-04-07 04:44:37 +02:00
/**
* @ endsection
*/
2009-04-06 03:20:13 +02:00
/**
* Generic player attributes .
2009-08-13 18:31:21 +02:00
*
* Stuff that must be updated when new attributes are added :
* ZR_CLASS_DEFAULT_ ... define
* ZR_CLASS_ ... _MAX / MIN defines
* ZR_CLASS_ ... define ( place in same order as listed in ClassAttributes , bump bit numbers + update numbers in docs )
* ClassLoad
* ClassReloadDataCache
* ClassReloadPlayerCache
* ClassDumpData
* attributes . inc - Add new Get - function
* ClassAttributeNameToFlag
* ClassGetAttributeType
* ClassValidateAttributes
* ClassModify * in classcommands . inc
* Update docs with detailed attribute description
2009-04-06 03:20:13 +02:00
*/
enum ClassAttributes
{
/* General */
2009-08-13 18:31:21 +02:00
bool : Class_Enabled ,
Class_Team ,
bool : Class_TeamDefault ,
Class_Flags ,
String : Class_Group [ 64 ],
2009-04-06 03:20:13 +02:00
2009-08-13 18:31:21 +02:00
String : Class_Name [ 64 ],
String : Class_Description [ 256 ],
2009-04-06 03:20:13 +02:00
/* Model */
2009-08-13 18:31:21 +02:00
String : Class_ModelPath [ PLATFORM_MAX_PATH ],
Class_AlphaInitial ,
Class_AlphaDamaged ,
Class_AlphaDamage ,
2009-04-06 03:20:13 +02:00
/* Hud */
2009-08-13 18:31:21 +02:00
String : Class_OverlayPath [ PLATFORM_MAX_PATH ],
bool : Class_Nvgs ,
Class_Fov ,
2009-04-06 03:20:13 +02:00
/* Effects */
2009-08-13 18:31:21 +02:00
bool : Class_HasNapalm ,
Float : Class_NapalmTime ,
2009-04-06 03:20:13 +02:00
/* Player behaviour */
2009-08-13 18:31:21 +02:00
Class_ImmunityMode ,
Float : Class_ImmunityAmount ,
bool : Class_NoFallDamage ,
Class_Health ,
Float : Class_HealthRegenInterval ,
Class_HealthRegenAmount ,
Class_HealthInfectGain ,
Class_KillBonus ,
Float : Class_Speed ,
Float : Class_KnockBack ,
Float : Class_JumpHeight ,
Float : Class_JumpDistance
2009-05-10 18:49:47 +02:00
}
2009-09-27 23:45:17 +02:00
/**
* Structure of class attributes that are allowed to be modified directly ,
* while the player is alive .
*
* Note : This structure is also used as a mask to tell if a individual
* attribute should be ignored or not . Negative valueas usually indicate
* ignored attributes . Booleans are now ints so they can be negative .
* Strings have reserved keywords like " nochange " that indicate a ignored
* attribute .
*/
enum ClassEditableAttributes
{
/* Model */
ClassEdit_AlphaInitial = 0 ,
ClassEdit_AlphaDamaged ,
ClassEdit_AlphaDamage ,
/* Hud */
String : ClassEdit_OverlayPath [ PLATFORM_MAX_PATH ],
ClassEdit_Nvgs ,
ClassEdit_Fov ,
/* Effects */
ClassEdit_HasNapalm ,
Float : ClassEdit_NapalmTime ,
/* Player behaviour */
ClassEdit_ImmunityMode ,
Float : ClassEdit_ImmunityAmount ,
ClassEdit_NoFallDamage ,
Float : ClassEdit_RegenInterval ,
ClassEdit_RegenAmount ,
ClassEdit_InfectGain ,
ClassEdit_KillBonus ,
Float : ClassEdit_Speed ,
Float : ClassEdit_KnockBack ,
Float : ClassEdit_JumpHeight ,
Float : ClassEdit_JumpDistance
}
2009-06-18 02:09:55 +02:00
/**
* 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
}
2009-05-10 18:49:47 +02:00
/**
* Data types used in class attributes .
*/
enum ClassDataTypes
{
ClassDataType_InvalidType , /** Invalid type */
ClassDataType_Boolean , /** Boolean value */
ClassDataType_Integer , /** Integer value */
ClassDataType_Float , /** Floating point value */
ClassDataType_String /** String value */
2009-04-06 03:20:13 +02:00
}
2009-08-14 22:10:52 +02:00
/**
* Structure for class filter settings passed to various functions .
*/
enum ClassFilter
{
bool : ClassFilter_IgnoreEnabled , /** Ignore whether the class is disabled or not. */
ClassFilter_RequireFlags , /** Flags the classes must have set. */
ClassFilter_DenyFlags , /** Flags the classes cannot have set. */
2009-08-15 17:37:30 +02:00
ClassFilter_Client /** The client to check for class group permissions. Use 0 to ignore group filter and negative to exclude classes with groups set. */
2009-08-14 22:10:52 +02:00
}
2010-07-04 17:58:27 +02:00
/**
* Speed methods for applying player speed .
*/
enum ClassSpeedMethods
{
ClassSpeed_Invalid = - 1 ,
ClassSpeed_LMV , /** Modifies lagged movement value. */
ClassSpeed_Prop , /** Modifies players' max speed property(m_flMaxspeed). */
}
2009-08-14 22:10:52 +02:00
/**
* Empty filter structure .
*/
new ClassNoFilter [ ClassFilter ];
/**
* Filter structure for excluding special classes .
*/
new ClassNoSpecialClasses [ ClassFilter ] = { false , 0 , ZR_CLASS_SPECIALFLAGS , - 1 };
2009-04-06 03:20:13 +02:00
/**
* The original class data . This array only changed when class data is loaded .
* ZR_CLASS_CACHE_ORIGINAL is the cache type to this array .
*/
new ClassData [ ZR_CLASS_MAX ][ ClassAttributes ];
/**
* The class thata cache that can be modified . ZR_CLASS_CACHE_MODIFIED is the
* cache type to this array .
*/
new ClassDataCache [ ZR_CLASS_MAX ][ ClassAttributes ];
/**
* Cache for player attributes . Makes it possible for one or more players to
* have custom attributes . ZR_CLASS_CACHE_PLAYER is the cache type to this
* array .
*/
new ClassPlayerCache [ MAXPLAYERS + 1 ][ ClassAttributes ];
2009-06-18 02:09:55 +02:00
/**
* 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 ];
2009-04-06 03:20:13 +02:00
/**
2009-04-11 01:56:22 +02:00
* Number of classes loaded .
2009-04-06 03:20:13 +02:00
*/
new ClassCount ;
2009-05-10 18:49:47 +02:00
/**
2009-11-17 08:47:39 +01:00
* Specifies whether the class team requirements and attributes are valid or not .
2009-05-10 18:49:47 +02:00
* Used to block events that happend before the module is done loading .
*/
new bool : ClassValidated ;
2009-04-06 03:20:13 +02:00
/**
2009-07-22 14:06:18 +02:00
* Stores what class the player has selected , for each team .
2009-04-06 03:20:13 +02:00
*/
2009-04-11 01:56:22 +02:00
new ClassSelected [ MAXPLAYERS + 1 ][ ZR_CLASS_TEAMCOUNT ];
2009-04-06 03:20:13 +02:00
2009-07-22 14:06:18 +02:00
/**
2009-07-23 23:26:14 +02:00
* Stores what class to be restored on next spawn , if available .
2009-07-22 14:06:18 +02:00
*/
2009-07-23 23:26:14 +02:00
new ClassSelectedNext [ MAXPLAYERS + 1 ][ ZR_CLASS_TEAMCOUNT ];
2009-07-22 14:06:18 +02:00
2009-06-18 02:09:55 +02:00
/**
* Cache for the currently selected team ( admin menus ) .
*/
new ClassAdminTeamSelected [ MAXPLAYERS + 1 ];
2009-08-15 06:32:44 +02:00
/**
* Cookies for storing class indexes .
*/
new Handle : g_hClassCookieClassSelected [ ZR_CLASS_TEAMCOUNT ];
2009-06-18 02:09:55 +02:00
/**
* Cache for the currently selected attribute multiplier ( admin menus ) .
*/
new ClassMultipliers : ClassAdminAttributeSelected [ MAXPLAYERS + 1 ];
2009-04-14 23:33:06 +02:00
/**
* Specifies whether a player is currently in admin mode .
*/
new bool : ClassPlayerInAdminMode [ MAXPLAYERS + 1 ];
2009-04-25 14:19:14 +02:00
/**
2009-08-10 19:01:43 +02:00
* Specifies whether a player is allowed to change class with instant effect .
* This is only used on human classes , and in combination with the
* zr_classes_change_timelimit time limit , but could be used other places too .
* The class menu will automatically check this setting and apply attributes if
* set to true .
2009-04-25 14:19:14 +02:00
*/
2009-08-10 19:01:43 +02:00
new bool : ClassAllowInstantChange [ MAXPLAYERS + 1 ];
2009-04-25 14:19:14 +02:00
2009-06-22 17:01:26 +02:00
/**
* Cache for storing original model path before applying custom models . Used
* when restoring to old model .
*/
new String : ClassOriginalPlayerModel [ MAXPLAYERS + 1 ][ PLATFORM_MAX_PATH ];
2009-11-20 18:20:45 +01:00
/**
* Specifies whether a player has spawned .
*/
new bool : ClassPlayerSpawned [ MAXPLAYERS + 1 ];
2010-07-04 17:58:27 +02:00
/**
* What method used to apply speed on players .
*/
new ClassSpeedMethods : ClassSpeedMethod = ClassSpeed_Prop ;
2009-04-06 03:20:13 +02:00
#include "zr/playerclasses/filtertools"
#include "zr/playerclasses/attributes"
#include "zr/playerclasses/apply"
#include "zr/playerclasses/clientoverlays"
2009-04-11 01:56:22 +02:00
#include "zr/playerclasses/clientalpha"
2009-04-07 02:13:25 +02:00
#include "zr/playerclasses/healthregen"
2009-04-11 01:56:22 +02:00
#include "zr/playerclasses/classevents"
2009-04-15 23:40:45 +02:00
#include "zr/playerclasses/classmenus"
#include "zr/playerclasses/classcommands"
2009-04-06 03:20:13 +02:00
/**
2009-04-19 01:10:30 +02:00
* Loads class attributes from the class file into ClassData array . If any
2009-05-18 06:26:13 +02:00
* error occur the plugin load will fail , and errors will be logged .
2009-06-18 02:09:55 +02:00
*
* @ param keepMultipliers Optional . Don ' t reset multipliers . Default is
* false .
2009-04-06 03:20:13 +02:00
*/
2009-11-11 22:50:19 +01:00
ClassLoad ()
2009-04-06 03:20:13 +02:00
{
2009-05-29 08:43:15 +02:00
// Register config file.
ConfigRegisterConfig ( File_Classes , Structure_Keyvalue , CONFIG_FILE_ALIAS_CLASSES );
2009-11-17 08:47:39 +01:00
new Handle : kvClassData ;
2009-04-06 03:20:13 +02:00
// Make sure kvClassData is ready to use.
2009-05-29 08:43:15 +02:00
kvClassData = CreateKeyValues ( CONFIG_FILE_ALIAS_CLASSES );
2009-04-06 03:20:13 +02:00
2009-05-01 07:09:18 +02:00
// Get weapons config path.
decl String : pathclasses [ PLATFORM_MAX_PATH ];
2009-05-18 06:26:13 +02:00
new bool : exists = ConfigGetCvarFilePath ( CVAR_CONFIG_PATH_CLASSES , pathclasses );
2009-05-01 07:09:18 +02:00
// If file doesn't exist, then log and stop.
if ( ! exists )
2009-04-06 03:20:13 +02:00
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Missing playerclasses config file \" %s \" " , pathclasses );
2009-07-24 02:05:04 +02:00
// Remove key/value cache.
CloseHandle ( kvClassData );
kvClassData = INVALID_HANDLE ;
2009-05-01 07:09:18 +02:00
return ;
2009-04-06 03:20:13 +02:00
}
2009-05-10 18:49:47 +02:00
// Log what class file that is loaded.
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Normal , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Loading classes from file \" %s \" . " , pathclasses );
2009-05-10 18:49:47 +02:00
2009-05-01 07:09:18 +02:00
// Put file data into memory.
FileToKeyValues ( kvClassData , pathclasses );
2009-04-06 03:20:13 +02:00
// Try to find the first class.
KvRewind ( kvClassData );
if ( ! KvGotoFirstSubKey ( kvClassData ))
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Can't find any classes in \" %s \" " , pathclasses );
2009-04-06 03:20:13 +02:00
}
decl String : name [ 64 ];
2009-08-13 18:31:21 +02:00
decl String : group [ 64 ];
2009-04-06 03:20:13 +02:00
decl String : description [ 256 ];
2009-04-25 14:19:14 +02:00
decl String : model_path [ PLATFORM_MAX_PATH ];
decl String : overlay_path [ PLATFORM_MAX_PATH ];
2009-04-06 03:20:13 +02:00
ClassCount = 0 ;
2009-05-09 17:45:19 +02:00
new failedcount ;
2009-04-07 04:44:37 +02:00
new ClassErrorFlags ;
2009-04-06 03:20:13 +02:00
// Loop through all classes and store attributes in the ClassData array.
do
{
2011-07-10 13:37:00 +02:00
if ( ClassCount >= ZR_CLASS_MAX )
2009-04-06 03:20:13 +02:00
{
// Maximum classes reached. Write a warning and exit the loop.
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Warning: Maximum classes reached (%d). Skipping other classes. " , ZR_CLASS_MAX + 1 );
2009-04-06 03:20:13 +02:00
break ;
}
/* General */
2009-08-15 02:58:49 +02:00
ClassData [ ClassCount ][ Class_Enabled ] = ConfigKvGetStringBool ( kvClassData , " enabled " , ZR_CLASS_DEFAULT_ENABLED );
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_Team ] = KvGetNum ( kvClassData , " team " , ZR_CLASS_DEFAULT_TEAM );
2009-08-15 02:58:49 +02:00
ClassData [ ClassCount ][ Class_TeamDefault ] = ConfigKvGetStringBool ( kvClassData , " team_default " , ZR_CLASS_DEFAULT_TEAM_DEFAULT );
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_Flags ] = KvGetNum ( kvClassData , " flags " , ZR_CLASS_DEFAULT_FLAGS );
KvGetString ( kvClassData , " group " , group , sizeof ( group ), ZR_CLASS_DEFAULT_GROUP );
strcopy ( ClassData [ ClassCount ][ Class_Group ], 64 , group );
2009-04-06 03:20:13 +02:00
KvGetString ( kvClassData , " name " , name , sizeof ( name ), ZR_CLASS_DEFAULT_NAME );
2009-08-13 18:31:21 +02:00
strcopy ( ClassData [ ClassCount ][ Class_Name ], 64 , name );
2009-04-06 03:20:13 +02:00
KvGetString ( kvClassData , " description " , description , sizeof ( description ), ZR_CLASS_DEFAULT_DESCRIPTION );
2009-08-13 18:31:21 +02:00
strcopy ( ClassData [ ClassCount ][ Class_Description ], 256 , description );
2009-04-06 03:20:13 +02:00
/* Model */
KvGetString ( kvClassData , " model_path " , model_path , sizeof ( model_path ), ZR_CLASS_DEFAULT_MODEL_PATH );
2009-08-13 18:31:21 +02:00
strcopy ( ClassData [ ClassCount ][ Class_ModelPath ], PLATFORM_MAX_PATH , model_path );
2009-04-06 03:20:13 +02:00
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_AlphaInitial ] = KvGetNum ( kvClassData , " alpha_initial " , ZR_CLASS_DEFAULT_ALPHA_INITIAL );
ClassData [ ClassCount ][ Class_AlphaDamaged ] = KvGetNum ( kvClassData , " alpha_damaged " , ZR_CLASS_DEFAULT_ALPHA_DAMAGED );
ClassData [ ClassCount ][ Class_AlphaDamage ] = KvGetNum ( kvClassData , " alpha_damage " , ZR_CLASS_DEFAULT_ALPHA_DAMAGE );
2009-04-06 03:20:13 +02:00
/* Hud */
KvGetString ( kvClassData , " overlay_path " , overlay_path , sizeof ( overlay_path ), ZR_CLASS_DEFAULT_OVERLAY_PATH );
2009-08-13 18:31:21 +02:00
strcopy ( ClassData [ ClassCount ][ Class_OverlayPath ], PLATFORM_MAX_PATH , overlay_path );
2009-04-06 03:20:13 +02:00
2009-08-15 02:58:49 +02:00
ClassData [ ClassCount ][ Class_Nvgs ] = ConfigKvGetStringBool ( kvClassData , " nvgs " , ZR_CLASS_DEFAULT_NVGS );
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_Fov ] = KvGetNum ( kvClassData , " fov " , ZR_CLASS_DEFAULT_FOV );
2009-04-06 03:20:13 +02:00
/* Effects */
2009-09-27 23:45:17 +02:00
ClassData [ ClassCount ][ Class_HasNapalm ] = ConfigKvGetStringBool ( kvClassData , " has_napalm " , ZR_CLASS_DEFAULT_HAS_NAPALM );
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_NapalmTime ] = KvGetFloat ( kvClassData , " napalm_time " , ZR_CLASS_DEFAULT_NAPALM_TIME );
2009-04-06 03:20:13 +02:00
/* Player behaviour */
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_ImmunityMode ] = KvGetNum ( kvClassData , " immunity_mode " , ZR_CLASS_DEFAULT_IMMUNITY_MODE );
ClassData [ ClassCount ][ Class_ImmunityAmount ] = KvGetFloat ( kvClassData , " immunity_amount " , ZR_CLASS_DEFAULT_IMMUNITY_AMOUNT );
2009-08-15 02:58:49 +02:00
ClassData [ ClassCount ][ Class_NoFallDamage ] = ConfigKvGetStringBool ( kvClassData , " no_fall_damage " , ZR_CLASS_DEFAULT_NO_FALL_DAMAGE );
2009-04-06 03:20:13 +02:00
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_Health ] = KvGetNum ( kvClassData , " health " , ZR_CLASS_DEFAULT_HEALTH );
ClassData [ ClassCount ][ Class_HealthRegenInterval ] = KvGetFloat ( kvClassData , " health_regen_interval " , ZR_CLASS_DEFAULT_HEALTH_REGEN_INTERVAL );
ClassData [ ClassCount ][ Class_HealthRegenAmount ] = KvGetNum ( kvClassData , " health_regen_amount " , ZR_CLASS_DEFAULT_HEALTH_REGEN_AMOUNT );
ClassData [ ClassCount ][ Class_HealthInfectGain ] = KvGetNum ( kvClassData , " health_infect_gain " , ZR_CLASS_DEFAULT_HEALTH_INFECT_GAIN );
ClassData [ ClassCount ][ Class_KillBonus ] = KvGetNum ( kvClassData , " kill_bonus " , ZR_CLASS_DEFAULT_KILL_BONUS );
2009-04-06 03:20:13 +02:00
2009-08-13 18:31:21 +02:00
ClassData [ ClassCount ][ Class_Speed ] = KvGetFloat ( kvClassData , " speed " , ZR_CLASS_DEFAULT_SPEED );
ClassData [ ClassCount ][ Class_KnockBack ] = KvGetFloat ( kvClassData , " knockback " , ZR_CLASS_DEFAULT_KNOCKBACK );
ClassData [ ClassCount ][ Class_JumpHeight ] = KvGetFloat ( kvClassData , " jump_height " , ZR_CLASS_DEFAULT_JUMP_HEIGHT );
ClassData [ ClassCount ][ Class_JumpDistance ] = KvGetFloat ( kvClassData , " jump_distance " , ZR_CLASS_DEFAULT_JUMP_DISTANCE );
2009-04-06 03:20:13 +02:00
2012-05-30 11:35:34 +02:00
// Validate class attributes if class is enabled.
if ( ClassData [ ClassCount ][ Class_Enabled ])
2009-04-06 03:20:13 +02:00
{
2012-05-30 11:35:34 +02:00
ClassErrorFlags = ClassValidateAttributes ( ClassCount , true );
if ( ClassErrorFlags > 0 )
{
// There's one or more invalid class attributes. Disable the class
// and log an error message.
ClassData [ ClassCount ][ Class_Enabled ] = false ;
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Warning: Invalid class at index %d, disabled class. Class error flags: %d. " , ClassCount , ClassErrorFlags );
failedcount ++ ;
}
2009-04-06 03:20:13 +02:00
}
2009-04-11 01:56:22 +02:00
2009-04-07 04:44:37 +02:00
// Update the counter.
ClassCount ++ ;
2009-04-06 03:20:13 +02:00
} while ( KvGotoNextKey ( kvClassData ));
// Validate team requirements.
if ( ! ClassValidateTeamRequirements ())
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " The class configuration doesn't match the team requirements. " );
2009-04-06 03:20:13 +02:00
}
2009-04-11 01:56:22 +02:00
// Validate team default requirements.
if ( ! ClassValidateTeamDefaults ())
{
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Fatal , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Couldn't find a default class for one or more teams. At least one class per team must be marked as default. " );
2009-04-11 01:56:22 +02:00
}
// Cache class data.
ClassReloadDataCache ();
2009-05-09 17:45:19 +02:00
2009-07-23 23:26:14 +02:00
// Reset selected class indexes for next spawn.
ClassResetNextIndexes ();
2009-07-22 14:06:18 +02:00
2009-05-10 18:49:47 +02:00
// Mark classes as valid.
ClassValidated = true ;
2009-05-09 17:45:19 +02:00
// Log summary.
2009-06-01 23:29:26 +02:00
LogEvent ( false , LogType_Normal , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Total: %d | Successful: %d | Unsuccessful: %d " , ClassCount , ClassCount - failedcount , failedcount );
2009-05-18 06:26:13 +02:00
// Set config data.
2009-05-29 08:43:15 +02:00
ConfigSetConfigLoaded ( File_Classes , true );
ConfigSetConfigReloadFunc ( File_Classes , GetFunctionByName ( GetMyHandle (), " ClassOnConfigReload " ));
ConfigSetConfigPath ( File_Classes , pathclasses );
2009-06-22 18:11:31 +02:00
// Remove key/value cache.
CloseHandle ( kvClassData );
2009-06-23 01:26:02 +02:00
kvClassData = INVALID_HANDLE ;
2009-04-06 03:20:13 +02:00
}
2009-05-18 06:26:13 +02:00
/**
* Called when configs are being reloaded .
*
* @ param config The config being reloaded . ( only if 'all' is false )
*/
public ClassOnConfigReload ( ConfigFile : config )
{
// Reload class config.
2009-11-11 22:50:19 +01:00
ClassLoad ();
2009-05-18 06:26:13 +02:00
}
2009-05-14 02:28:26 +02:00
2010-07-04 17:58:27 +02:00
/**
* Gets the speed method .
*
* @ return Speed method , or ClassSpeed_Invalid on error .
*/
ClassSpeedMethods : ClassGetSpeedMethod ()
{
decl String : speedMethod [ 16 ];
speedMethod [ 0 ] = 0 ;
GetConVarString ( g_hCvarsList [ CVAR_CLASSES_SPEED_METHOD ], speedMethod , sizeof ( speedMethod ));
if ( StrEqual ( speedMethod , " lmv " , false ))
{
return ClassSpeed_LMV ;
}
else if ( StrEqual ( speedMethod , " prop " , false ))
{
return ClassSpeed_Prop ;
}
return ClassSpeed_Invalid ;
}
2009-04-06 03:20:13 +02:00
/**
* Updates the class data cache . Original values are retrieved from ClassData .
*
* @ return True on success , false otherwise .
*/
bool : ClassReloadDataCache ()
{
2009-04-25 14:19:14 +02:00
// Check if there are no classes.
2009-04-06 03:20:13 +02:00
if ( ClassCount == 0 )
{
return false ;
}
2009-04-25 14:19:14 +02:00
// Loop through all classes.
2009-04-11 01:56:22 +02:00
for ( new classindex = 0 ; classindex < ClassCount ; classindex ++ )
2009-04-06 03:20:13 +02:00
{
/* General */
2009-08-13 18:31:21 +02:00
ClassDataCache [ classindex ][ Class_Enabled ] = ClassData [ classindex ][ Class_Enabled ];
ClassDataCache [ classindex ][ Class_Team ] = ClassData [ classindex ][ Class_Team ];
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_Name ], 64 , ClassData [ classindex ][ Class_Name ]);
strcopy ( ClassDataCache [ classindex ][ Class_Description ], 256 , ClassData [ classindex ][ Class_Description ]);
2009-04-06 03:20:13 +02:00
/* Model */
2009-08-13 18:31:21 +02:00
strcopy ( ClassDataCache [ classindex ][ Class_ModelPath ], PLATFORM_MAX_PATH , ClassData [ classindex ][ Class_ModelPath ]);
ClassDataCache [ classindex ][ Class_AlphaInitial ] = ClassData [ classindex ][ Class_AlphaInitial ];
ClassDataCache [ classindex ][ Class_AlphaDamaged ] = ClassData [ classindex ][ Class_AlphaDamaged ];
ClassDataCache [ classindex ][ Class_AlphaDamage ] = ClassData [ classindex ][ Class_AlphaDamage ];
2009-04-06 03:20:13 +02:00
/* Hud */
2009-08-13 18:31:21 +02:00
strcopy ( ClassDataCache [ classindex ][ Class_OverlayPath ], PLATFORM_MAX_PATH , ClassData [ classindex ][ Class_OverlayPath ]);
ClassDataCache [ classindex ][ Class_Nvgs ] = ClassData [ classindex ][ Class_Nvgs ];
ClassDataCache [ classindex ][ Class_Fov ] = ClassData [ classindex ][ Class_Fov ];
2009-04-06 03:20:13 +02:00
/* Effects */
2009-08-13 18:31:21 +02:00
ClassDataCache [ classindex ][ Class_HasNapalm ] = ClassData [ classindex ][ Class_HasNapalm ];
ClassDataCache [ classindex ][ Class_NapalmTime ] = ClassData [ classindex ][ Class_NapalmTime ];
2009-04-06 03:20:13 +02:00
/* Player behaviour */
2009-08-13 18:31:21 +02:00
ClassDataCache [ classindex ][ Class_ImmunityMode ] = ClassData [ classindex ][ Class_ImmunityMode ];
ClassDataCache [ classindex ][ Class_ImmunityAmount ] = ClassData [ classindex ][ Class_ImmunityAmount ];
ClassDataCache [ classindex ][ Class_NoFallDamage ] = ClassData [ classindex ][ Class_NoFallDamage ];
ClassDataCache [ classindex ][ Class_Health ] = ClassData [ classindex ][ Class_Health ];
ClassDataCache [ classindex ][ Class_HealthRegenInterval ] = ClassData [ classindex ][ Class_HealthRegenInterval ];
ClassDataCache [ classindex ][ Class_HealthRegenAmount ] = ClassData [ classindex ][ Class_HealthRegenAmount ];
ClassDataCache [ classindex ][ Class_HealthInfectGain ] = ClassData [ classindex ][ Class_HealthInfectGain ];
ClassDataCache [ classindex ][ Class_KillBonus ] = ClassData [ classindex ][ Class_KillBonus ];
ClassDataCache [ classindex ][ Class_Speed ] = ClassData [ classindex ][ Class_Speed ];
ClassDataCache [ classindex ][ Class_KnockBack ] = ClassData [ classindex ][ Class_KnockBack ];
ClassDataCache [ classindex ][ Class_JumpHeight ] = ClassData [ classindex ][ Class_JumpHeight ];
ClassDataCache [ classindex ][ Class_JumpDistance ] = ClassData [ classindex ][ Class_JumpDistance ];
2009-04-06 03:20:13 +02:00
}
return true ;
}
/**
2009-06-18 02:09:55 +02:00
* Refresh the specified player ' s cache from the specified class data cache .
2009-04-06 03:20:13 +02:00
*
* @ param client The client index .
* @ param classindex The index of the class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options : ZR_CLASS_CACHE_ORIGINAL ( unchanged class
* data ), ZR_CLASS_CACHE_MODIFIED ( default , modified class
* data ) .
* @ return True if successful , false otherwise .
*/
bool : ClassReloadPlayerCache ( client , classindex , cachetype = ZR_CLASS_CACHE_MODIFIED )
{
// Validate indexes.
2009-04-24 05:02:19 +02:00
if ( ! ClassValidateIndex ( classindex ) || ! ZRIsClientValid ( client ))
2009-04-06 03:20:13 +02:00
{
return false ;
}
switch ( cachetype )
{
case ZR_CLASS_CACHE_ORIGINAL :
{
/* General */
2009-08-13 18:31:21 +02:00
ClassPlayerCache [ client ][ Class_Enabled ] = ClassData [ classindex ][ Class_Enabled ];
ClassPlayerCache [ client ][ Class_Team ] = ClassData [ classindex ][ Class_Team ];
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_Name ], 64 , ClassData [ classindex ][ Class_Name ]);
strcopy ( ClassPlayerCache [ client ][ Class_Description ], 256 , ClassData [ classindex ][ Class_Description ]);
2009-04-06 03:20:13 +02:00
/* Model */
2009-08-13 18:31:21 +02:00
strcopy ( ClassPlayerCache [ client ][ Class_ModelPath ], PLATFORM_MAX_PATH , ClassData [ classindex ][ Class_ModelPath ]);
ClassPlayerCache [ client ][ Class_AlphaInitial ] = ClassData [ classindex ][ Class_AlphaInitial ];
ClassPlayerCache [ client ][ Class_AlphaDamaged ] = ClassData [ classindex ][ Class_AlphaDamaged ];
ClassPlayerCache [ client ][ Class_AlphaDamage ] = ClassData [ classindex ][ Class_AlphaDamage ];
2009-04-06 03:20:13 +02:00
/* Hud */
2009-08-13 18:31:21 +02:00
strcopy ( ClassPlayerCache [ client ][ Class_OverlayPath ], PLATFORM_MAX_PATH , ClassData [ classindex ][ Class_OverlayPath ]);
ClassPlayerCache [ client ][ Class_Nvgs ] = ClassData [ classindex ][ Class_Nvgs ];
ClassPlayerCache [ client ][ Class_Fov ] = ClassData [ classindex ][ Class_Fov ];
2009-04-06 03:20:13 +02:00
/* Effects */
2009-08-13 18:31:21 +02:00
ClassPlayerCache [ client ][ Class_HasNapalm ] = ClassData [ classindex ][ Class_HasNapalm ];
ClassPlayerCache [ client ][ Class_NapalmTime ] = ClassData [ classindex ][ Class_NapalmTime ];
2009-04-06 03:20:13 +02:00
/* Player behaviour */
2009-08-13 18:31:21 +02:00
ClassPlayerCache [ client ][ Class_ImmunityMode ] = ClassData [ classindex ][ Class_ImmunityMode ];
ClassPlayerCache [ client ][ Class_ImmunityAmount ] = ClassData [ classindex ][ Class_ImmunityAmount ];
ClassPlayerCache [ client ][ Class_NoFallDamage ] = ClassData [ classindex ][ Class_NoFallDamage ];
ClassPlayerCache [ client ][ Class_Health ] = ClassData [ classindex ][ Class_Health ];
ClassPlayerCache [ client ][ Class_HealthRegenInterval ] = ClassData [ classindex ][ Class_HealthRegenInterval ];
ClassPlayerCache [ client ][ Class_HealthRegenAmount ] = ClassData [ classindex ][ Class_HealthRegenAmount ];
ClassPlayerCache [ client ][ Class_HealthInfectGain ] = ClassData [ classindex ][ Class_HealthInfectGain ];
ClassPlayerCache [ client ][ Class_KillBonus ] = ClassData [ classindex ][ Class_KillBonus ];
ClassPlayerCache [ client ][ Class_Speed ] = ClassData [ classindex ][ Class_Speed ];
ClassPlayerCache [ client ][ Class_KnockBack ] = ClassData [ classindex ][ Class_KnockBack ];
ClassPlayerCache [ client ][ Class_JumpHeight ] = ClassData [ classindex ][ Class_JumpHeight ];
ClassPlayerCache [ client ][ Class_JumpDistance ] = ClassData [ classindex ][ Class_JumpDistance ];
2009-04-06 03:20:13 +02:00
}
case ZR_CLASS_CACHE_MODIFIED :
{
/* General */
2009-08-13 18:31:21 +02:00
ClassPlayerCache [ client ][ Class_Enabled ] = ClassDataCache [ classindex ][ Class_Enabled ];
ClassPlayerCache [ client ][ Class_Team ] = ClassDataCache [ classindex ][ Class_Team ];
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_Name ], 64 , ClassDataCache [ classindex ][ Class_Name ]);
strcopy ( ClassPlayerCache [ client ][ Class_Description ], 256 , ClassDataCache [ classindex ][ Class_Description ]);
2009-04-06 03:20:13 +02:00
/* Model */
2009-08-13 18:31:21 +02:00
strcopy ( ClassPlayerCache [ client ][ Class_ModelPath ], PLATFORM_MAX_PATH , ClassDataCache [ classindex ][ Class_ModelPath ]);
ClassPlayerCache [ client ][ Class_AlphaInitial ] = ClassDataCache [ classindex ][ Class_AlphaInitial ];
ClassPlayerCache [ client ][ Class_AlphaDamaged ] = ClassDataCache [ classindex ][ Class_AlphaDamaged ];
ClassPlayerCache [ client ][ Class_AlphaDamage ] = ClassDataCache [ classindex ][ Class_AlphaDamage ];
2009-04-06 03:20:13 +02:00
/* Hud */
2009-08-13 18:31:21 +02:00
strcopy ( ClassPlayerCache [ client ][ Class_OverlayPath ], PLATFORM_MAX_PATH , ClassDataCache [ classindex ][ Class_OverlayPath ]);
ClassPlayerCache [ client ][ Class_Nvgs ] = ClassDataCache [ classindex ][ Class_Nvgs ];
ClassPlayerCache [ client ][ Class_Fov ] = ClassDataCache [ classindex ][ Class_Fov ];
2009-04-06 03:20:13 +02:00
/* Effects */
2009-08-13 18:31:21 +02:00
ClassPlayerCache [ client ][ Class_HasNapalm ] = ClassDataCache [ classindex ][ Class_HasNapalm ];
ClassPlayerCache [ client ][ Class_NapalmTime ] = ClassDataCache [ classindex ][ Class_NapalmTime ];
2009-04-06 03:20:13 +02:00
/* Player behaviour */
2009-08-13 18:31:21 +02:00
ClassPlayerCache [ client ][ Class_ImmunityMode ] = ClassDataCache [ classindex ][ Class_ImmunityMode ];
ClassPlayerCache [ client ][ Class_ImmunityAmount ] = ClassDataCache [ classindex ][ Class_ImmunityAmount ];
ClassPlayerCache [ client ][ Class_NoFallDamage ] = ClassDataCache [ classindex ][ Class_NoFallDamage ];
ClassPlayerCache [ client ][ Class_Health ] = ClassDataCache [ classindex ][ Class_Health ];
ClassPlayerCache [ client ][ Class_HealthRegenInterval ] = ClassDataCache [ classindex ][ Class_HealthRegenInterval ];
ClassPlayerCache [ client ][ Class_HealthRegenAmount ] = ClassDataCache [ classindex ][ Class_HealthRegenAmount ];
ClassPlayerCache [ client ][ Class_HealthInfectGain ] = ClassDataCache [ classindex ][ Class_HealthInfectGain ];
ClassPlayerCache [ client ][ Class_KillBonus ] = ClassDataCache [ classindex ][ Class_KillBonus ];
ClassPlayerCache [ client ][ Class_Speed ] = ClassDataCache [ classindex ][ Class_Speed ];
ClassPlayerCache [ client ][ Class_KnockBack ] = ClassDataCache [ classindex ][ Class_KnockBack ];
ClassPlayerCache [ client ][ Class_JumpHeight ] = ClassDataCache [ classindex ][ Class_JumpHeight ];
ClassPlayerCache [ client ][ Class_JumpDistance ] = ClassDataCache [ classindex ][ Class_JumpDistance ];
2009-04-06 03:20:13 +02:00
}
default :
{
// Invalid cache specified.
return false ;
}
}
return true ;
}
2009-04-11 01:56:22 +02:00
2009-06-18 03:33:09 +02:00
/**
* Refresh the specified player ' s cache and re - apply attributes .
*
* @ param client The client index .
* @ return True if successful , false otherwise .
*/
bool : ClassReloadPlayer ( client )
{
new activeclass ;
// Get active class index.
activeclass = ClassGetActiveIndex ( client );
// Validate index.
if ( activeclass < 0 )
{
return false ;
}
// Refresh cache and re-apply attributes.
2009-07-23 23:26:14 +02:00
ClassOnClientDeath ( client ); // Dummy event to clean up and turn off stuff.
2009-06-18 03:33:09 +02:00
ClassReloadPlayerCache ( client , activeclass );
ClassApplyAttributes ( client );
return true ;
}
2009-06-18 02:09:55 +02:00
/**
* 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 ;
}
}
2009-07-22 14:06:18 +02:00
/**
2009-08-13 18:31:21 +02:00
* Resets the selected class indexes for next spawn on one or all clients .
2009-07-22 14:06:18 +02:00
*
* @ param client Optional . Specify client to reset . Default is all .
*/
2009-07-23 23:26:14 +02:00
ClassResetNextIndexes ( client = - 1 )
2009-07-22 14:06:18 +02:00
{
new teamid ;
if ( client > 0 )
{
for ( teamid = 0 ; teamid < ZR_CLASS_TEAMCOUNT ; teamid ++ )
{
2009-07-23 23:26:14 +02:00
ClassSelectedNext [ client ][ teamid ] = - 1 ;
2009-07-22 14:06:18 +02:00
}
}
else
{
for ( client = 1 ; client <= MAXPLAYERS ; client ++ )
{
for ( teamid = 0 ; teamid < ZR_CLASS_TEAMCOUNT ; teamid ++ )
{
2009-07-23 23:26:14 +02:00
ClassSelectedNext [ client ][ teamid ] = - 1 ;
2009-07-22 14:06:18 +02:00
}
}
}
}
/**
2009-07-23 23:26:14 +02:00
* Restores next class indexes on a player , if available .
2009-07-22 14:06:18 +02:00
* Note : Does not apply attributes . The classes are only marked as selected .
*
2009-07-23 23:26:14 +02:00
* @ param client The client index .
2009-08-13 18:31:21 +02:00
* @ param excludeTeam Optional . Do not restore the specified team .
2009-07-22 14:06:18 +02:00
*/
2009-07-23 23:26:14 +02:00
ClassRestoreNextIndexes ( client , excludeTeam = - 1 )
2009-07-22 14:06:18 +02:00
{
2009-07-23 23:26:14 +02:00
// Get next class indexes.
new zombie = ClassSelectedNext [ client ][ ZR_CLASS_TEAM_ZOMBIES ];
new human = ClassSelectedNext [ client ][ ZR_CLASS_TEAM_HUMANS ];
new admin = ClassSelectedNext [ client ][ ZR_CLASS_TEAM_ADMINS ];
2009-07-22 14:06:18 +02:00
2009-07-23 23:26:14 +02:00
// Check if the zombie team should be excluded.
if ( excludeTeam != ZR_CLASS_TEAM_ZOMBIES )
2009-07-22 14:06:18 +02:00
{
2009-07-23 23:26:14 +02:00
// Validate zombie class index.
if ( ClassValidateIndex ( zombie ))
{
// Mark next zombie class as selected.
ClassSelected [ client ][ ZR_CLASS_TEAM_ZOMBIES ] = zombie ;
}
// Reset index.
ClassSelectedNext [ client ][ ZR_CLASS_TEAM_ZOMBIES ] = - 1 ;
2009-07-22 14:06:18 +02:00
}
2009-07-23 23:26:14 +02:00
// Check if the human team should be excluded.
if ( excludeTeam != ZR_CLASS_TEAM_HUMANS )
2009-07-22 14:06:18 +02:00
{
2009-07-23 23:26:14 +02:00
// Validate human class index.
if ( ClassValidateIndex ( human ))
{
// Mark next zombie class as selected.
ClassSelected [ client ][ ZR_CLASS_TEAM_HUMANS ] = human ;
}
// Reset index.
ClassSelectedNext [ client ][ ZR_CLASS_TEAM_HUMANS ] = - 1 ;
2009-07-22 14:06:18 +02:00
}
2009-07-23 23:26:14 +02:00
// Check if the human team should be excluded.
if ( excludeTeam != ZR_CLASS_TEAM_ADMINS )
2009-07-22 14:06:18 +02:00
{
2009-07-23 23:26:14 +02:00
// Validate admin class index.
if ( ClassValidateIndex ( admin ))
{
// Mark next zombie class as selected.
ClassSelected [ client ][ ZR_CLASS_TEAM_ADMINS ] = admin ;
}
// Reset index.
ClassSelectedNext [ client ][ ZR_CLASS_TEAM_ADMINS ] = - 1 ;
2009-07-22 14:06:18 +02:00
}
}
2009-04-11 01:56:22 +02:00
/**
* Sets default class indexes for each team on all players , or a single player
* if specified .
*
2009-08-15 06:32:44 +02:00
* @ param client Optional . The client index . If specified , cookies are used .
2009-04-11 01:56:22 +02:00
*/
ClassClientSetDefaultIndexes ( client = - 1 )
{
2009-08-15 06:32:44 +02:00
new bool : clientvalid = ZRIsClientValid ( client );
2009-08-15 17:37:30 +02:00
new filter [ ClassFilter ];
2009-08-15 19:48:51 +02:00
new bool : saveclasses = GetConVarBool ( g_hCvarsList [ CVAR_CLASSES_SAVE ]);
2009-08-15 17:37:30 +02:00
2009-08-15 06:32:44 +02:00
new zombieindex ;
new humanindex ;
new adminindex ;
new bool : haszombie ;
new bool : hashuman ;
new bool : hasadmin ;
2009-10-10 17:37:30 +02:00
/*
* SETUP CLASS FILTER
*/
// Do not require any class flags to be set.
filter [ ClassFilter_RequireFlags ] = 0 ;
// Set filter to hide mother zombie classes.
filter [ 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 ;
// Specify client so it can check group permissions.
filter [ ClassFilter_Client ] = client ;
/*
* GET CLASS INDEXES
*/
2009-08-15 06:32:44 +02:00
// Check if a client is specified.
if ( clientvalid )
{
2009-08-15 19:48:51 +02:00
// 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 ;
}
2009-08-15 06:32:44 +02:00
// 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.
2009-10-10 17:37:30 +02:00
// Check if class indexes are set and that the client pass the filter.
2010-04-05 00:57:41 +02:00
// Also check that the saved class' team id match with the loaded class.
2009-10-10 17:37:30 +02:00
// If not, fall back to default class indexes. Otherwise substract
// index by one.
2010-04-05 00:57:41 +02:00
if ( zombieindex <= 0 ||
2010-06-03 21:12:28 +02:00
! ClassTeamCompare ( zombieindex - 1 , ZR_CLASS_TEAM_ZOMBIES ) ||
2010-04-05 00:57:41 +02:00
! ClassFilterMatch ( zombieindex - 1 , filter ))
2009-08-15 06:32:44 +02:00
{
2009-08-15 17:37:30 +02:00
zombieindex = ClassGetDefaultSpawnClass ( ZR_CLASS_TEAM_ZOMBIES , filter );
2009-08-15 06:32:44 +02:00
}
else
{
zombieindex -- ;
haszombie = true ;
}
2010-04-05 00:57:41 +02:00
if ( humanindex <= 0 ||
2010-06-03 21:12:28 +02:00
! ClassTeamCompare ( humanindex - 1 , ZR_CLASS_TEAM_HUMANS ) ||
2010-04-05 00:57:41 +02:00
! ClassFilterMatch ( humanindex - 1 , filter ))
2009-08-15 06:32:44 +02:00
{
2009-08-15 17:37:30 +02:00
humanindex = ClassGetDefaultSpawnClass ( ZR_CLASS_TEAM_HUMANS , filter );
2009-08-15 06:32:44 +02:00
}
else
{
humanindex -- ;
hashuman = true ;
}
2010-04-05 00:57:41 +02:00
if ( adminindex <= 0 ||
2010-06-03 21:12:28 +02:00
! ClassTeamCompare ( adminindex - 1 , ZR_CLASS_TEAM_ADMINS ) ||
2010-04-05 00:57:41 +02:00
! ClassFilterMatch ( adminindex - 1 , filter ))
2009-08-15 06:32:44 +02:00
{
2009-08-15 17:37:30 +02:00
adminindex = ClassGetDefaultSpawnClass ( ZR_CLASS_TEAM_ADMINS , filter );
2009-08-15 06:32:44 +02:00
}
else
{
adminindex -- ;
hasadmin = true ;
}
}
else
{
2009-10-10 17:37:30 +02:00
// Set filter to exclude classes that require groups.
2009-08-15 17:37:30 +02:00
filter [ ClassFilter_Client ] = - 1 ;
2009-08-15 06:32:44 +02:00
// Get default class indexes.
2009-08-15 17:37:30 +02:00
zombieindex = ClassGetDefaultSpawnClass ( ZR_CLASS_TEAM_ZOMBIES , filter );
humanindex = ClassGetDefaultSpawnClass ( ZR_CLASS_TEAM_HUMANS , filter );
adminindex = ClassGetDefaultSpawnClass ( ZR_CLASS_TEAM_ADMINS , filter );
2009-08-15 06:32:44 +02:00
}
2009-04-11 01:56:22 +02:00
2009-10-10 17:37:30 +02:00
/*
* VALIDATE INDEXES
*/
2009-04-11 01:56:22 +02:00
if ( ! ClassValidateIndex ( zombieindex ))
{
// Invalid class index. Fall back to default class in class config and
// log a warning.
2009-10-27 22:53:03 +01:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Playerclasses , " Set Default Indexes " , " Warning: Failed to get the specified zombie class, falling back to default class in class config. Check spelling in \" zr_classes_default_zombie \" . " );
2009-04-11 01:56:22 +02:00
// Use default class.
2009-08-15 17:37:30 +02:00
zombieindex = ClassGetDefaultClass ( ZR_CLASS_TEAM_ZOMBIES , filter );
2009-04-11 01:56:22 +02:00
}
if ( ! ClassValidateIndex ( humanindex ))
{
// Invalid class index. Fall back to default class in class config and
// log a warning.
2009-10-27 22:53:03 +01:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Playerclasses , " Set Default Indexes " , " Warning: Failed to get the specified human class, falling back to default class in class config. Check spelling in \" zr_classes_default_human \" . " );
2009-04-11 01:56:22 +02:00
// Use default class.
2009-08-15 17:37:30 +02:00
humanindex = ClassGetDefaultClass ( ZR_CLASS_TEAM_HUMANS , filter );
2009-04-11 01:56:22 +02:00
}
if ( ! ClassValidateIndex ( adminindex ))
{
2009-04-25 14:19:14 +02:00
// Invalid class index. Fall back to default class in class config if
// possible. A invalid class index (-1) can also be stored if there are
// no admin classes at all.
2009-08-15 17:37:30 +02:00
adminindex = ClassGetDefaultClass ( ZR_CLASS_TEAM_ADMINS , filter );
2009-04-11 01:56:22 +02:00
}
2009-10-10 17:37:30 +02:00
/*
* MARK INDEXES AS SELECTED , UPDATE CACHE AND COOKIES
*/
2009-08-15 06:32:44 +02:00
// Check if a client is specified.
if ( clientvalid )
{
// Set selected class idexes.
ClassSelected [ client ][ ZR_CLASS_TEAM_ZOMBIES ] = zombieindex ;
ClassSelected [ client ][ ZR_CLASS_TEAM_HUMANS ] = humanindex ;
ClassSelected [ client ][ ZR_CLASS_TEAM_ADMINS ] = adminindex ;
// Copy human class data to player cache.
ClassReloadPlayerCache ( client , humanindex );
2009-08-15 19:48:51 +02:00
// Save indexes in cookies if enabled, and not already saved.
if ( saveclasses )
2009-08-15 06:32:44 +02:00
{
2009-08-15 19:48:51 +02:00
if ( ! haszombie )
{
CookiesSetInt ( client , g_hClassCookieClassSelected [ ZR_CLASS_TEAM_ZOMBIES ], zombieindex + 1 );
}
if ( ! hashuman )
{
CookiesSetInt ( client , g_hClassCookieClassSelected [ ZR_CLASS_TEAM_HUMANS ], humanindex + 1 );
}
if ( ! hasadmin )
{
CookiesSetInt ( client , g_hClassCookieClassSelected [ ZR_CLASS_TEAM_ADMINS ], adminindex + 1 );
}
2009-08-15 06:32:44 +02:00
}
}
else
2009-04-11 01:56:22 +02:00
{
// No client specified. Loop through all players.
2009-08-15 06:32:44 +02:00
for ( new clientindex = 1 ; clientindex <= MaxClients ; clientindex ++ )
2009-04-11 01:56:22 +02:00
{
2009-08-15 06:32:44 +02:00
// Set selected class idexes.
2009-04-11 01:56:22 +02:00
ClassSelected [ clientindex ][ ZR_CLASS_TEAM_ZOMBIES ] = zombieindex ;
ClassSelected [ clientindex ][ ZR_CLASS_TEAM_HUMANS ] = humanindex ;
ClassSelected [ clientindex ][ ZR_CLASS_TEAM_ADMINS ] = adminindex ;
// Copy human class data to player cache.
ClassReloadPlayerCache ( client , humanindex );
}
}
}
2009-04-15 23:40:45 +02:00
/**
* Dump class data into a string . String buffer length should be at about 2048
* cells .
*
* @ 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 :
* 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 Number of cells written .
*/
2009-05-02 18:08:33 +02:00
ClassDumpData ( index , cachetype , String : buffer [], maxlen )
2009-04-15 23:40:45 +02:00
{
new cellcount ;
decl String : attribute [ 320 ];
decl String : format_buffer [ 256 ];
if ( maxlen == 0 )
{
return 0 ;
}
Format ( format_buffer , sizeof ( format_buffer ), " Class data at index %d: \n " , index );
cellcount += StrCat ( buffer , maxlen , format_buffer );
cellcount += StrCat ( buffer , maxlen , " ------------------------------------------------------------------------------- \n " );
Format ( attribute , sizeof ( attribute ), " enabled: \" %d \" \n " , ClassIsEnabled ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " team: \" %d \" \n " , ClassGetTeamID ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " team_default: \" %d \" \n " , ClassGetTeamDefault ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
2009-06-22 01:09:51 +02:00
Format ( attribute , sizeof ( attribute ), " flags: \" %d \" \n " , ClassGetFlags ( index , cachetype ));
2009-06-19 02:31:05 +02:00
cellcount += StrCat ( buffer , maxlen , attribute );
2009-08-13 18:31:21 +02:00
ClassGetGroup ( index , format_buffer , sizeof ( format_buffer ), cachetype );
2009-08-14 22:10:52 +02:00
Format ( attribute , sizeof ( attribute ), " group: \" %s \" \n " , format_buffer );
2009-08-13 18:31:21 +02:00
cellcount += StrCat ( buffer , maxlen , attribute );
2009-04-15 23:40:45 +02:00
ClassGetName ( index , format_buffer , sizeof ( format_buffer ), cachetype );
Format ( attribute , sizeof ( attribute ), " name: \" %s \" \n " , format_buffer );
cellcount += StrCat ( buffer , maxlen , attribute );
ClassGetDescription ( index , format_buffer , sizeof ( format_buffer ), cachetype );
Format ( attribute , sizeof ( attribute ), " description: \" %s \" \n " , format_buffer );
cellcount += StrCat ( buffer , maxlen , attribute );
ClassGetModelPath ( index , format_buffer , sizeof ( format_buffer ), cachetype );
Format ( attribute , sizeof ( attribute ), " model_path: \" %s \" \n " , format_buffer );
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " alpha_initial: \" %d \" \n " , ClassGetAlphaInitial ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " alpha_damaged: \" %d \" \n " , ClassGetAlphaDamaged ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " alpha_damage: \" %d \" \n " , ClassGetAlphaDamage ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
ClassGetOverlayPath ( index , format_buffer , sizeof ( format_buffer ), cachetype );
Format ( attribute , sizeof ( attribute ), " overlay_path: \" %s \" \n " , format_buffer );
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " nvgs: \" %d \" \n " , ClassGetNvgs ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " fov: \" %d \" \n " , ClassGetFOV ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
2009-06-14 19:10:30 +02:00
Format ( attribute , sizeof ( attribute ), " has_napalm: \" %d \" \n " , ClassGetHasNapalm ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
2009-04-15 23:40:45 +02:00
Format ( attribute , sizeof ( attribute ), " napalm_time: \" %f \" \n " , ClassGetNapalmTime ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " immunity_mode: \" %d \" \n " , ClassGetImmunityMode ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " immunity_amount: \" %f \" \n " , ClassGetImmunityAmount ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " no_fall_damage: \" %d \" \n " , ClassGetNoFallDamage ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " health: \" %d \" \n " , ClassGetHealth ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " health_regen_interval: \" %f \" \n " , ClassGetHealthRegenInterval ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " health_regen_amount: \" %d \" \n " , ClassGetHealthRegenAmount ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " health_infect_gain: \" %d \" \n " , ClassGetHealthInfectGain ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " kill_bonus: \" %d \" \n " , ClassGetKillBonus ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " speed: \" %f \" \n " , ClassGetSpeed ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " knockback: \" %f \" \n " , ClassGetKnockback ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " jump_height: \" %f \" \n " , ClassGetJumpHeight ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
Format ( attribute , sizeof ( attribute ), " jump_distance: \" %f \" \n " , ClassGetJumpDistance ( index , cachetype ));
cellcount += StrCat ( buffer , maxlen , attribute );
return cellcount ;
}
2009-06-18 02:09:55 +02:00
/**
* Converts a multiplier attribute to a human readable string .
*
2009-07-28 02:02:49 +02:00
* @ param client The client index to translate correct language .
2009-06-18 02:09:55 +02:00
* @ param attribute Attribute to convert .
* @ param buffer Destination string buffer .
* @ param maxlen Size of buffer .
* @ return Number of cells written .
*/
2009-07-28 02:02:49 +02:00
ClassMultiplierToString ( client , ClassMultipliers : attribute , String : buffer [], maxlen )
2009-06-18 02:09:55 +02:00
{
decl String : phrase [ 48 ];
2009-07-28 02:02:49 +02:00
SetGlobalTransTarget ( client );
2009-06-18 02:09:55 +02:00
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 ;
}