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 : apply . inc
* Type : Core
* Description : Functions for applying attributes and effects on a client .
*
2013-01-12 08:47:36 +01:00
* Copyright ( C ) 2009 - 2013 Greyscale , Richard Helgeby
2009-06-12 05:51:26 +02:00
*
* 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
*
* ============================================================================
*/
2010-07-04 17:58:27 +02:00
/**
* Array that stores the client ' s current speed .
*/
new Float : g_flClassApplySpeed [ MAXPLAYERS + 1 ];
2009-04-06 03:20:13 +02:00
/**
* Applies all class attributes on a player . Changing model , hp , speed , health ,
* effects etc . The players current team will be used to get the class index .
*
* @ param client The player to apply attributes on .
* @ param improved Optional . Gives advantages or improvements in some
* attributes . To be used on mother zombies . Default is
* false .
* @ return True if all success on applying all attributes , false otherwise .
*/
bool : ClassApplyAttributes ( client , bool : improved = false )
{
new classindex = ClassGetActiveIndex ( client );
2016-02-06 00:47:47 +01:00
2009-06-22 01:09:51 +02:00
// Validate class index.
if ( ! ClassValidateIndex ( classindex ))
2009-04-06 03:20:13 +02:00
{
return false ;
}
2016-02-06 00:47:47 +01:00
2009-06-22 01:09:51 +02:00
// Override improved settings if it's a mother zombie class.
if ( ClassHasFlags ( classindex , ZR_CLASS_FLAG_MOTHER_ZOMBIE ))
{
improved = false ;
}
2016-02-06 00:47:47 +01:00
2009-04-06 03:20:13 +02:00
ClassApplyModel ( client , classindex );
ClassApplyAlpha ( client , classindex );
ClassApplyOverlay ( client , classindex );
2009-04-07 02:13:25 +02:00
ClassApplyNightVision ( client , classindex );
ClassApplyFOV ( client , classindex );
ClassApplyHealth ( client , classindex , improved );
2018-06-28 15:39:17 +02:00
ClassApplyHealthRegen ( client , classindex , improved );
2009-04-07 02:13:25 +02:00
ClassApplySpeed ( client , classindex );
2016-02-06 00:47:47 +01:00
2009-04-11 01:56:22 +02:00
return true ;
2009-04-06 03:20:13 +02:00
}
/**
* Changes the model on a player .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
2009-04-11 01:56:22 +02:00
bool : ClassApplyModel ( client , classindex , cachetype = ZR_CLASS_CACHE_PLAYER )
2009-04-06 03:20:13 +02:00
{
2009-11-17 08:47:39 +01:00
new bool : isAttributePreset = false ;
2009-04-18 01:44:41 +02:00
decl String : modelpath [ PLATFORM_MAX_PATH ];
2009-11-17 08:47:39 +01:00
new index ;
new ModelTeam : team ;
new access ;
new model ;
2013-04-25 09:50:08 +02:00
new skinIndex = 0 ;
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Get correct index according to cache type.
2009-04-06 03:20:13 +02:00
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
2009-11-17 08:47:39 +01:00
index = client ;
2009-04-06 03:20:13 +02:00
}
else
{
2009-11-17 08:47:39 +01:00
index = classindex ;
2009-04-06 03:20:13 +02:00
}
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Get the model path from the specified cache.
ClassGetModelPath ( index , modelpath , sizeof ( modelpath ), cachetype );
2016-02-06 00:47:47 +01:00
2013-04-25 09:50:08 +02:00
// Get model skin index.
skinIndex = ClassGetModelSkinIndex ( index , cachetype );
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Get model team setting from the specified cache.
team = ModelsTeamIdToTeam ( ClassGetTeamID ( index , cachetype ));
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Check if the user specified a pre-defined model setting. If so, setup
// model filter settings.
2009-08-15 03:33:09 +02:00
if ( StrEqual ( modelpath , " random " , false ))
2009-04-06 03:20:13 +02:00
{
2009-11-17 08:47:39 +01:00
// Set access filter flags.
access = MODEL_ACCESS_PUBLIC | MODEL_ACCESS_ADMINS ;
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Specify client for including admin models if client is admin.
index = client ;
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
isAttributePreset = true ;
}
else if ( StrEqual ( modelpath , " random_public " , false ))
{
access = MODEL_ACCESS_PUBLIC ;
index = - 1 ;
isAttributePreset = true ;
}
else if ( StrEqual ( modelpath , " random_hidden " , false ))
{
access = MODEL_ACCESS_HIDDEN ;
index = - 1 ;
isAttributePreset = true ;
}
else if ( StrEqual ( modelpath , " random_admin " , false ))
{
access = MODEL_ACCESS_ADMINS ;
index = - 1 ;
isAttributePreset = true ;
}
else if ( StrEqual ( modelpath , " random_mother_zombie " , false ))
{
access = MODEL_ACCESS_MOTHER_ZOMBIES ;
index = - 1 ;
isAttributePreset = true ;
2009-04-06 03:20:13 +02:00
}
2009-08-15 03:33:09 +02:00
else if ( StrEqual ( modelpath , " default " , false ))
2009-04-25 14:19:14 +02:00
{
2009-06-22 17:01:26 +02:00
// Get current model.
GetClientModel ( client , modelpath , sizeof ( modelpath ));
2016-02-06 00:47:47 +01:00
2009-06-22 17:01:26 +02:00
// Restore original model if not already set.
if ( ! StrEqual ( ClassOriginalPlayerModel [ client ], modelpath ))
{
strcopy ( modelpath , sizeof ( modelpath ), ClassOriginalPlayerModel [ client ]);
}
else
{
// Wanted model is already set, don't change.
return true ;
}
2009-04-25 14:19:14 +02:00
}
2009-11-17 08:47:39 +01:00
else if ( StrEqual ( modelpath , " no_change " , false ))
2009-08-15 03:33:09 +02:00
{
// Do nothing.
return true ;
}
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Check if model setting is a attribute preset.
if ( isAttributePreset )
{
// Get model based on filter settings set up earlier.
model = ModelsGetRandomModel ( index , team , access );
2016-02-06 00:47:47 +01:00
2009-11-17 08:47:39 +01:00
// Check if found.
if ( model >= 0 )
{
// Get model path.
ModelsGetFullPath ( model , modelpath , sizeof ( modelpath ));
}
else
{
// Couldn't find any models based on filter. Fall back to a random
// public model. Then get its path.
model = ModelsGetRandomModel ( - 1 , team , MODEL_ACCESS_PUBLIC );
ModelsGetFullPath ( model , modelpath , sizeof ( modelpath ));
}
}
2016-02-06 00:47:47 +01:00
2018-08-13 16:07:04 +02:00
// Check if the model is precached.
if ( ! IsModelPrecached ( modelpath ))
{
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Playerclasses , " Config Validation " , " Warning: Model not precached, not applying model. \" %s \" " , modelpath );
return true ;
}
2009-04-15 21:22:11 +02:00
SetEntityModel ( client , modelpath );
2013-04-25 09:50:08 +02:00
SetEntProp ( client , Prop_Send , " m_nSkin " , skinIndex );
2016-02-06 00:47:47 +01:00
2009-04-06 03:20:13 +02:00
return true ;
}
/**
* Sets transparency on a player .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
bool : ClassApplyAlpha ( client , classindex , cachetype = ZR_CLASS_CACHE_PLAYER )
{
2009-04-11 01:56:22 +02:00
new alpha ;
2016-02-06 00:47:47 +01:00
2009-04-11 01:56:22 +02:00
// Get the alpha value from the specified cache.
2009-04-06 03:20:13 +02:00
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
2009-04-11 01:56:22 +02:00
alpha = ClassGetAlphaInitial ( client , cachetype );
2009-04-06 03:20:13 +02:00
}
else
{
2009-04-11 01:56:22 +02:00
alpha = ClassGetAlphaInitial ( classindex , cachetype );
2009-04-06 03:20:13 +02:00
}
2016-02-06 00:47:47 +01:00
2009-04-06 03:20:13 +02:00
if ( alpha < 0 )
{
return false ;
}
2016-02-06 00:47:47 +01:00
2009-04-29 01:58:41 +02:00
ToolsSetClientAlpha ( client , alpha );
2009-04-11 01:56:22 +02:00
return true ;
2009-04-06 03:20:13 +02:00
}
/**
* Apply the overlay on a player if not applied .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
bool : ClassApplyOverlay ( client , classindex , cachetype = ZR_CLASS_CACHE_PLAYER )
{
2009-04-18 01:44:41 +02:00
decl String : overlaypath [ PLATFORM_MAX_PATH ];
2016-02-06 00:47:47 +01:00
2009-04-06 03:20:13 +02:00
// Get the overlay path from the specified cache.
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
2009-04-18 01:44:41 +02:00
ClassGetOverlayPath ( client , overlaypath , sizeof ( overlaypath ), cachetype );
2009-04-06 03:20:13 +02:00
}
else
{
2009-04-18 01:44:41 +02:00
ClassGetOverlayPath ( classindex , overlaypath , sizeof ( overlaypath ), cachetype );
2009-04-06 03:20:13 +02:00
}
2016-02-06 00:47:47 +01:00
2009-04-18 01:44:41 +02:00
ClassOverlayInitialize ( client , overlaypath );
2009-04-06 03:20:13 +02:00
return true ;
}
2009-04-07 02:13:25 +02:00
/**
* Gives night vision to a player .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
bool : ClassApplyNightVision ( client , classindex , cachetype = ZR_CLASS_CACHE_PLAYER )
{
new bool : nvgs ;
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
// Get the night vision setting from the specified cache.
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
nvgs = ClassGetNvgs ( client , cachetype );
}
else
{
nvgs = ClassGetNvgs ( classindex , cachetype );
}
2016-02-06 00:47:47 +01:00
2009-07-07 06:32:34 +02:00
ToolsSetClientNightVision ( client , nvgs );
2017-07-05 23:00:50 +02:00
if ( ! nvgs )
ToolsSetClientNightVision ( client , nvgs , false );
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
return true ;
}
/**
* Sets the field of view setting on a player .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
bool : ClassApplyFOV ( client , classindex , cachetype = ZR_CLASS_CACHE_PLAYER )
{
new fov ;
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
// Get the field of view setting from the specified cache.
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
fov = ClassGetFOV ( client , cachetype );
}
else
{
fov = ClassGetFOV ( classindex , cachetype );
}
2016-02-06 00:47:47 +01:00
2009-04-29 01:58:41 +02:00
ToolsSetClientDefaultFOV ( client , fov );
2009-04-07 02:13:25 +02:00
return true ;
}
/**
* Gives health points on a player .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param boost Double health boost . Default : false
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
bool : ClassApplyHealth ( client , classindex , bool : boost = false , cachetype = ZR_CLASS_CACHE_PLAYER )
{
new health ;
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
// Get the health points from the specified cache.
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
health = ClassGetHealth ( client , cachetype );
}
else
{
health = ClassGetHealth ( classindex , cachetype );
}
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
if ( boost )
{
health *= 2 ;
}
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
SetEntityHealth ( client , health );
return true ;
}
/**
* Applies health regeneration on a player if enabled .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param boost Double health boost . Default : false
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True if applied , false otherwise .
*/
2018-06-28 15:39:17 +02:00
bool : ClassApplyHealthRegen ( client , classindex , bool : boost = false , cachetype = ZR_CLASS_CACHE_PLAYER )
2009-04-07 02:13:25 +02:00
{
new Float : interval ;
new amount ;
new max ;
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
// Get the health regeneration info from the specified cache.
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
interval = ClassGetHealthRegenInterval ( client , cachetype );
amount = ClassGetHealthRegenAmount ( client , cachetype );
max = ClassGetHealth ( client , cachetype );
}
else
{
interval = ClassGetHealthRegenInterval ( classindex , cachetype );
amount = ClassGetHealthRegenAmount ( classindex , cachetype );
max = ClassGetHealth ( classindex , cachetype );
}
2016-02-06 00:47:47 +01:00
2018-06-28 15:39:17 +02:00
if ( boost )
{
max *= 2 ;
}
2009-04-07 02:13:25 +02:00
if ( interval > 0 )
{
2009-12-03 01:22:20 +01:00
ClassHealthRegenInitClient ( client , interval , amount , max );
2009-04-07 02:13:25 +02:00
return true ;
}
else
{
2009-10-31 03:39:00 +01:00
// Make sure old timers are stopped.
ClassHealthRegenStop ( client );
2009-04-07 02:13:25 +02:00
return false ;
}
}
/**
* Sets the players speed .
*
* @ param client The client index .
* @ param classindex The class to read from .
* @ param cachetype Optional . Specifies what class cache to read from .
* Options :
* ZR_CLASS_CACHE_ORIGINAL - Unchanced class data .
* ZR_CLASS_CACHE_MODIFIED - Changed / newest class data .
* ZR_CLASS_CACHE_PLAYER ( default ) - Player cache .
* @ return True on success , false otherwise .
*/
bool : ClassApplySpeed ( client , classindex , cachetype = ZR_CLASS_CACHE_PLAYER )
{
2009-04-11 01:56:22 +02:00
new Float : speed ;
2016-02-06 00:47:47 +01:00
2009-04-07 02:13:25 +02:00
// Get the health points from the specified cache.
if ( cachetype == ZR_CLASS_CACHE_PLAYER )
{
speed = ClassGetSpeed ( client , cachetype );
}
else
{
speed = ClassGetSpeed ( classindex , cachetype );
}
2016-02-06 00:47:47 +01:00
2010-07-04 17:58:27 +02:00
ClassApplySpeedEx ( client , speed );
2009-04-07 02:13:25 +02:00
return true ;
}
2010-07-04 17:58:27 +02:00
/**
* Applies the specified speed to the player .
*
* @ param client Client to apply to .
* @ param speed Speed value .
*/
ClassApplySpeedEx ( client , Float : speed )
{
// Check what speed method that's used and apply it.
switch ( ClassSpeedMethod )
{
case ClassSpeed_LMV :
{
ToolsSetClientLMV ( client , speed );
}
case ClassSpeed_Prop :
{
g_flClassApplySpeed [ client ] = speed ;
}
}
}
/**
* Called before the client can " think "
* Here we can change the client ' s speed through m_flMaxSpeed .
2016-02-06 00:47:47 +01:00
*
2010-07-04 17:58:27 +02:00
* @ param client The client index .
*/
public ClassPreThinkPost ( client )
{
// Only apply speed if the prop method is used.
if ( ClassSpeedMethod == ClassSpeed_Prop )
{
if ( ! IsPlayerAlive ( client ))
{
return ;
}
2016-02-06 00:47:47 +01:00
2010-07-04 17:58:27 +02:00
// Note: Default is around 200.0 - 250.0
new Float : newspeed = GetEntPropFloat ( client , Prop_Data , " m_flMaxspeed " ) + g_flClassApplySpeed [ client ];
SetEntPropFloat ( client , Prop_Data , " m_flMaxspeed " , newspeed );
}
}
/**
* Called when a clients movement buttons are being processed
*
2018-07-30 21:53:45 +02:00
* @ param client Index of the client .
* @ param vel Players desired velocity .
2010-07-04 17:58:27 +02:00
*/
Class_OnPlayerRunCmd ( client , Float : vel [ 3 ])
{
if ( ! IsPlayerAlive ( client ))
return ;
2016-02-06 00:47:47 +01:00
2010-07-04 17:58:27 +02:00
// Only modify speed if the prop method is used.
if ( ClassSpeedMethod == ClassSpeed_Prop )
{
// x-axis speed.
if ( vel [ 0 ] < 0.0 )
vel [ 0 ] = - 5000.0 ;
2016-02-06 00:47:47 +01:00
2010-07-04 17:58:27 +02:00
else if ( vel [ 0 ] > 0.0 )
vel [ 0 ] = 5000.0 ;
2016-02-06 00:47:47 +01:00
2010-07-04 17:58:27 +02:00
// y-axis speed.
if ( vel [ 1 ] < 0.0 )
vel [ 1 ] = - 5000.0 ;
2016-02-06 00:47:47 +01:00
2010-07-04 17:58:27 +02:00
else if ( vel [ 1 ] > 0.0 )
vel [ 1 ] = 5000.0 ;
}
}