2009-05-16 01:37:23 +02:00
/*
* ============================================================================
*
2009-05-30 04:17:01 +02:00
* Zombie : Reloaded
2009-05-16 01:37:23 +02:00
*
2009-05-30 04:17:01 +02:00
* File : volfeatures . inc
* Type : Module
* Description : Provides functions for managing volumetric features .
*
* 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-05-16 01:37:23 +02:00
*
* ============================================================================
*/
/**
* Total volumes that can be created in a map .
*/
#define ZR_VOLUMES_MAX 64
/**
* Represent a rectangular volume .
*/
enum VolumeAttributes
{
/* General */
2009-07-16 10:05:40 +02:00
bool : Vol_Enabled , /** Volume state. */
bool : Vol_InUse , /** Marks if the volume is used. */
2009-05-16 01:37:23 +02:00
/* Location */
2009-07-16 10:05:40 +02:00
Float : Vol_xMin , /** Minimum x position. */
Float : Vol_xMax , /** Maximum x position. */
2009-05-16 01:37:23 +02:00
2009-07-16 10:05:40 +02:00
Float : Vol_yMin , /** Minimum y position. */
Float : Vol_yMax , /** Maximum y position. */
2009-05-16 01:37:23 +02:00
2009-07-16 10:05:40 +02:00
Float : Vol_zMin , /** Minimum z position. */
Float : Vol_zMax , /** Maximum z position. */
2009-05-30 04:17:01 +02:00
/* Style */
2009-07-16 10:05:40 +02:00
VolumeEffects : Vol_Effect , /** Visual effect to apply on the volume. */
Vol_EffectColor [ 3 ], /** Render color of the effect. RGB colors. */
2009-05-16 01:37:23 +02:00
/* Data */
2009-07-16 10:05:40 +02:00
VolumeFeatureTypes : Vol_Type , /** The volumetric feature type. */
Vol_DataIndex , /** Index in remote feature array. */
2009-05-30 04:17:01 +02:00
/* Behaviour */
2009-07-16 10:05:40 +02:00
VolumeTeamFilters : Vol_TeamFilter , /** Team filtering. Trigger by certain teams, or all. */
Float : Vol_TriggerDelay /** Trigger delay. How many seconds players have to stay to trigger volume events. */
2009-05-16 01:37:23 +02:00
}
/**
* Available volumetric feature types .
*/
enum VolumeFeatureTypes
{
2009-07-16 10:05:40 +02:00
VolFeature_Invalid = 0 ,
VolFeature_Anticamp ,
2009-05-16 01:37:23 +02:00
VolFeature_Knockback
}
2009-05-30 04:17:01 +02:00
/**
* Effects that can be applied on a volume . ( Currently no effects . )
*/
2009-05-16 01:37:23 +02:00
enum VolumeEffects
{
VolEffect_None = 0 ,
VolEffect_Wireframe ,
VolEffect_Smoke
}
2009-05-30 04:17:01 +02:00
/**
* Available team filter settings .
*/
enum VolumeTeamFilters
{
VolTeam_All = 0 ,
VolTeam_Humans ,
VolTeam_Zombies
}
2009-05-16 01:37:23 +02:00
/**
* Volumes .
*/
new Volumes [ ZR_VOLUMES_MAX ][ VolumeAttributes ];
/**
* Total number of volumes .
*/
new VolumeCount ;
/**
* List of player locations . Updated by a timer .
*/
new Float : VolPlayerLoc [ MAXPLAYERS + 1 ][ 3 ];
2009-07-16 10:05:40 +02:00
/**
* Cache that specifies if a player is in a volume or not .
*/
new bool : VolPlayerInVolume [ MAXPLAYERS + 1 ][ ZR_VOLUMES_MAX ];
2009-05-16 01:37:23 +02:00
/**
2009-05-30 04:17:01 +02:00
* Specifies whether the volumetric features module is enabled or not . Synced
* with zr_vol CVAR .
2009-05-16 01:37:23 +02:00
*/
new bool : VolEnabled ;
/**
2009-05-30 04:17:01 +02:00
* Counter for trigger delay .
*/
new Float : VolPlayerCountDown [ MAXPLAYERS + 1 ][ ZR_VOLUMES_MAX ];
/**
* The handle for a timer that updates player locations . This is the main timer
2009-05-16 01:37:23 +02:00
* and any feature events can ' t be updated faster than this interval .
*
2009-07-16 10:05:40 +02:00
* Note : Some features may have its own timer for actions on players .
2009-05-16 01:37:23 +02:00
*/
new Handle : hVolUpdateTimer ;
2009-05-30 04:17:01 +02:00
/**
* The handle for a timer that do count down on trigger delays .
*/
new Handle : hVolTriggerTimer ;
/**
* Cached interval value for trigger timer .
*/
new Float : VolTriggerInterval ;
2009-05-16 01:37:23 +02:00
#include "zr/volfeatures/volevents"
2009-05-30 04:17:01 +02:00
#include "zr/volfeatures/volgenericattributes"
#include "zr/volfeatures/volcommands"
2009-07-16 10:05:40 +02:00
// Sub features.
2009-05-16 01:37:23 +02:00
#include "zr/volfeatures/volanticamp"
2009-05-30 04:17:01 +02:00
/**
* Initialize volumetric features .
*/
VolLoad ()
{
// Cache CVAR value.
VolEnabled = GetConVarBool ( g_hCvarsList [ CVAR_VOL ]);
2009-07-16 10:05:40 +02:00
// Initialize sub features.
VolAnticampInit ();
2009-05-30 04:17:01 +02:00
}
/**
* Function alias for fully stopping volumetric features .
*/
VolDisable ()
{
VolEnabled = false ;
VolStopUpdateTimer ();
2009-07-16 10:05:40 +02:00
VolDisableVolumes ();
2009-05-30 04:17:01 +02:00
2009-07-16 10:05:40 +02:00
LogEvent ( _ , LogType_Normal , LOG_DEBUG , LogModule_Volfeatures , " Disabled " , " Volfeatures disabled. " );
}
/**
* Function alias for starting volumetric features .
*/
VolEnable ()
{
VolEnabled = true ;
VolStartUpdateTimer ();
VolEnableVolumes ();
LogEvent ( _ , LogType_Normal , LOG_DEBUG , LogModule_Volfeatures , " Enabled " , " Volfeatures enabled. " );
}
/**
* Disables all enabled volumes .
*/
VolDisableVolumes ()
{
// Trigger disable event on all enabled volumes in use.
for ( new volindex = 0 ; volindex < ZR_VOLUMES_MAX ; volindex ++ )
{
if ( Volumes [ volindex ][ Vol_InUse ] && Volumes [ volindex ][ Vol_Enabled ])
{
VolOnDisabled ( volindex );
}
}
}
/**
* Enables all disabled volumes .
*/
VolEnableVolumes ()
{
// Trigger enable event on all volumes in use.
for ( new volindex = 0 ; volindex < ZR_VOLUMES_MAX ; volindex ++ )
{
if ( Volumes [ volindex ][ Vol_InUse ] && ! Volumes [ volindex ][ Vol_Enabled ])
{
VolOnEnabled ( volindex );
}
}
2009-05-30 04:17:01 +02:00
}
2009-05-16 01:37:23 +02:00
/**
* Starts the update timer .
2009-05-30 04:17:01 +02:00
*
* @ return True if timer is started , false otherwise .
2009-05-16 01:37:23 +02:00
*/
bool : VolStartUpdateTimer ()
{
2009-05-30 04:17:01 +02:00
// Check if volumetric features is enabled.
2009-05-16 01:37:23 +02:00
if ( ! VolEnabled )
{
// Volumetric features disabled.
return false ;
}
2009-05-30 04:17:01 +02:00
// Stop timer if it exist.
VolStopUpdateTimer ();
// Get update interval.
new Float : interval = GetConVarFloat ( g_hCvarsList [ CVAR_VOL_UPDATE_INTERVAL ]);
2009-05-16 01:37:23 +02:00
// Validate interval.
if ( interval > 0.0 )
{
// Create a new timer.
hVolUpdateTimer = CreateTimer ( interval , Event_VolUpdateTimer , _ , TIMER_REPEAT );
2009-05-30 04:17:01 +02:00
// Also start the trigger delay timer.
VolStartTriggerTimer ();
2009-05-16 01:37:23 +02:00
// Volumetric features started.
return true ;
}
else
{
2009-07-16 10:05:40 +02:00
// Volumetric features disabled.
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Volfeatures , " Config Validation " , " Warning: Console variable \" zr_vol_update_interval \" is set to zero or negative. Must be positive. " );
2009-05-16 01:37:23 +02:00
return false ;
}
}
/**
* Kills the update timer if it exists .
*/
VolStopUpdateTimer ()
{
// Kill the timer if it's running.
if ( hVolUpdateTimer != INVALID_HANDLE )
{
KillTimer ( hVolUpdateTimer );
hVolUpdateTimer = INVALID_HANDLE ;
}
2009-05-30 04:17:01 +02:00
// Also stop trigger delay timer.
VolStopTriggerTimer ();
// Reset all trigger delay counters.
VolResetCountDown ();
}
/**
* Starts the update timer if it exists .
*
* @ return True if timer is started , false otherwise .
*/
bool : VolStartTriggerTimer ()
{
// Make sure existing timer is killed.
VolStopTriggerTimer ();
// Get trigger interval and cache it.
VolTriggerInterval = GetConVarFloat ( g_hCvarsList [ CVAR_VOL_TRIGGER_INTERVAL ]);
// Validate interval.
if ( VolTriggerInterval > 0.0 )
{
// Start the timer.
2009-07-16 10:05:40 +02:00
hVolTriggerTimer = CreateTimer ( VolTriggerInterval , Event_VolTriggerTimer , _ , TIMER_REPEAT );
2009-05-30 04:17:01 +02:00
// Trigger timer started.
return true ;
}
else
{
// Trigger timer not running. Either disabled or invalid interval.
2009-07-16 10:05:40 +02:00
LogEvent ( false , LogType_Error , LOG_CORE_EVENTS , LogModule_Volfeatures , " Config Validation " , " Warning: Console variable \" zr_vol_trigger_interval \" is set to zero or negative. Must be positive. " );
2009-05-30 04:17:01 +02:00
return false ;
}
}
/**
* Kills the trigger delay timer if it exists .
*/
VolStopTriggerTimer ()
{
// Kill the timer if it's running.
if ( hVolTriggerTimer != INVALID_HANDLE )
{
KillTimer ( hVolTriggerTimer );
hVolTriggerTimer = INVALID_HANDLE ;
}
}
/**
* Resets volume trigger delay counters on one or more players .
*
* @ param client Optional . Specifies a single player to reset . Default is
* - 1 , all players .
*/
VolResetCountDown ( client = - 1 )
{
// Check if a client is specified.
if ( client > - 1 )
{
// Reset volume counters.
for ( new volumeIndex = 0 ; volumeIndex < ZR_VOLUMES_MAX ; volumeIndex ++ )
{
VolPlayerCountDown [ client ][ volumeIndex ] = - 1.0 ;
}
}
else
{
// Reset all volume counters.
2009-06-03 01:37:37 +02:00
for ( new clientIndex = 0 ; clientIndex < MAXPLAYERS + 1 ; clientIndex ++ )
2009-05-30 04:17:01 +02:00
{
for ( new volumeIndex = 0 ; volumeIndex < ZR_VOLUMES_MAX ; volumeIndex ++ )
{
VolPlayerCountDown [ clientIndex ][ volumeIndex ] = - 1.0 ;
}
}
}
2009-05-16 01:37:23 +02:00
}
/**
* Updates all player locations . Used for initialization .
*
* Note : If a client is specified , it ' s NOT validated . This function assumes
* the specified client is in game and alive .
*
* @ param client Optional . Specify single client to be updated . Default is
* - 1.
*/
VolUpdatePlayerLocation ( client = - 1 )
{
2009-07-16 10:05:40 +02:00
if ( client > 0 )
2009-05-16 01:37:23 +02:00
{
// Assume the client is valid and save location in array.
GetClientAbsOrigin ( client , VolPlayerLoc [ client ]);
}
else
{
2009-05-30 04:17:01 +02:00
for ( client = 1 ; client <= MaxClients ; client ++ )
2009-05-16 01:37:23 +02:00
{
// Check if client is in game and alive.
if ( ! IsClientConnected ( client ) || ! IsClientInGame ( client ) || ! IsPlayerAlive ( client ))
{
return ;
}
// Save location in array.
GetClientAbsOrigin ( client , VolPlayerLoc [ client ]);
}
}
}
/**
* Updates player locations and trigger events for each player that enter or
* leave a volume .
*/
VolUpdatePlayerChanges ()
{
new bool : volumeStates [ ZR_VOLUMES_MAX ];
new bool : volumeNewStates [ ZR_VOLUMES_MAX ];
new bool : newState ;
new bool : oldState ;
2009-05-30 04:17:01 +02:00
new Float : trigger_delay ;
// Loop through all players.
2009-05-16 01:37:23 +02:00
for ( new client = 1 ; client <= MaxClients ; client ++ )
{
// Check if client is in game and alive.
if ( ! IsClientConnected ( client ) || ! IsClientInGame ( client ) || ! IsPlayerAlive ( client ))
{
2009-07-16 10:05:40 +02:00
// Skip client.
continue ;
2009-05-16 01:37:23 +02:00
}
2009-07-16 10:05:40 +02:00
// Get the current volume states based on player location cache.
2009-05-16 01:37:23 +02:00
VolGetPlayerStates ( client , volumeStates , sizeof ( volumeStates ));
// Update player location cache.
GetClientAbsOrigin ( client , VolPlayerLoc [ client ]);
// Get new volume states.
VolGetPlayerStates ( client , volumeNewStates , sizeof ( volumeNewStates ));
// Loop through each volume and compare states.
2009-07-16 10:05:40 +02:00
for ( new volumeIndex = 0 ; volumeIndex < ZR_VOLUMES_MAX ; volumeIndex ++ )
2009-05-16 01:37:23 +02:00
{
2009-07-16 10:05:40 +02:00
// Check if the volume is disabled and unused.
if ( ! VolInUse ( volumeIndex ) || ! VolIsEnabled ( volumeIndex ))
{
// Skip volume.
continue ;
}
// Check team filtering on the volume.
if ( ! VolTeamFilterMatch ( client , volumeIndex ))
{
// Team filter mismatch.
continue ;
}
2009-05-16 01:37:23 +02:00
newState = volumeNewStates [ volumeIndex ];
oldState = volumeStates [ volumeIndex ];
2009-07-16 10:05:40 +02:00
// Check for no change.
2009-05-16 01:37:23 +02:00
if ( newState == oldState )
{
// No change. Skip to next volume.
2009-07-16 10:05:40 +02:00
continue ;
2009-05-16 01:37:23 +02:00
}
2009-05-30 04:17:01 +02:00
// Check if client entered the volume.
2009-07-16 10:05:40 +02:00
if ( newState && ! oldState )
2009-05-16 01:37:23 +02:00
{
2009-05-30 04:17:01 +02:00
// Get trigger delay value.
2009-07-16 10:05:40 +02:00
trigger_delay = Volumes [ volumeIndex ][ Vol_TriggerDelay ];
2009-05-30 04:17:01 +02:00
// Check if the volume has a trigger delay.
if ( trigger_delay > 0.0 )
{
// Set count down value.
VolPlayerCountDown [ client ][ volumeIndex ] = trigger_delay ;
}
else
{
2009-07-16 10:05:40 +02:00
// Update cache.
VolPlayerInVolume [ client ][ volumeIndex ] = true ;
2009-05-30 04:17:01 +02:00
// No trigger delay, trigger event instantly.
VolOnPlayerEnter ( client , volumeIndex );
}
2009-05-16 01:37:23 +02:00
}
2009-05-30 04:17:01 +02:00
// Check if client left the volume.
2009-07-16 10:05:40 +02:00
else if ( ! newState && oldState )
2009-05-16 01:37:23 +02:00
{
2009-05-30 04:17:01 +02:00
// Make sure count down value is reset.
VolPlayerCountDown [ client ][ volumeIndex ] = - 1.0 ;
2009-07-16 10:05:40 +02:00
// Update cache.
VolPlayerInVolume [ client ][ volumeIndex ] = false ;
2009-05-30 04:17:01 +02:00
// Trigger event.
2009-05-16 01:37:23 +02:00
VolOnPlayerLeave ( client , volumeIndex );
}
}
}
}
/**
2009-07-16 10:05:40 +02:00
* Returns wether a point is within a certain location .
2009-05-16 01:37:23 +02:00
*
2009-07-16 10:05:40 +02:00
* @ param point The point to check .
2009-05-16 01:37:23 +02:00
* @ param min Minimum x , y and z values of the location .
* @ param max Maximum x , y and z values of the location .
* @ return True if the position is within min and max values . False
* otherwise .
*/
2009-07-16 10:05:40 +02:00
bool : IsPointInLocation ( Float : point [ 3 ], Float : min [ 3 ], Float : max [ 3 ])
2009-05-16 01:37:23 +02:00
{
2009-07-16 10:05:40 +02:00
// Cache to avoid re-indexing arrays.
new Float : posX = point [ 0 ];
new Float : posY = point [ 1 ];
new Float : posZ = point [ 2 ];
2009-05-16 01:37:23 +02:00
// Check if within x boundaries.
if (( posX >= min [ 0 ]) && ( posX <= max [ 0 ]))
{
// Check if within y boundaries.
if (( posY >= min [ 1 ]) && ( posY <= max [ 1 ]))
{
// Check if within x boundaries.
if (( posZ >= min [ 2 ]) && ( posZ <= max [ 2 ]))
{
2009-07-16 10:05:40 +02:00
// The point is within the location boundaries.
2009-05-16 01:37:23 +02:00
return true ;
}
}
}
2009-07-16 10:05:40 +02:00
// The point is outside the location boundaries.
2009-05-16 01:37:23 +02:00
return false ;
}
/**
* Returns wether a volume is marked as in use .
*
2009-05-30 04:17:01 +02:00
* Note : Does not validate index .
*
2009-05-16 01:37:23 +02:00
* @ param volumeIndex The volume index .
* @ return True if in use , false otherwise .
*/
2009-07-16 10:05:40 +02:00
bool : VolInUse ( volumeIndex )
2009-05-16 01:37:23 +02:00
{
2009-07-16 10:05:40 +02:00
return Volumes [ volumeIndex ][ Vol_InUse ];
}
/**
* Returns wether a volume is enabled or not .
*
* Note : Does not validate index .
*
* @ param volumeIndex The volume index .
* @ return True if enabled , false otherwise .
*/
bool : VolIsEnabled ( volumeIndex )
{
return Volumes [ volumeIndex ][ Vol_Enabled ];
2009-05-16 01:37:23 +02:00
}
2009-05-30 04:17:01 +02:00
/**
* Validates a volume index .
*
* @ param volumeIndex The volume index .
* @ return True if valid , false otherwise .
*/
bool : VolIsValidIndex ( volumeIndex )
{
if ( volumeIndex >= 0 && volumeIndex < ZR_VOLUMES_MAX )
{
return true ;
}
else
{
return false ;
}
}
2009-05-16 01:37:23 +02:00
/**
* Gets the first free volume index .
*
* @ return The first free volume index if successful , or - 1 if there are
* no free volumes .
*/
VolGetFreeVolume ()
{
// Loop through all volumes.
for ( new volumeIndex = 0 ; volumeIndex < ZR_VOLUMES_MAX ; volumeIndex ++ )
{
// Check if it's free.
2009-07-16 10:05:40 +02:00
if ( ! VolInUse ( volumeIndex ))
2009-05-16 01:37:23 +02:00
{
return volumeIndex ;
}
}
// No free volumes found.
return - 1 ;
}
2009-07-16 10:05:40 +02:00
/**
* Gets a free index in the data array for the specified volume type .
*
* @ param volumeType Volumetric feature type .
* @ return Data index , or - 1 on error .
*/
VolGetFreeDataIndex ( VolumeFeatureTypes : volumeType )
{
switch ( volumeType )
{
case VolFeature_Anticamp :
{
return VolAnticampGetFreeIndex ();
}
case VolFeature_Knockback :
{
// TOTO: Finish incomplete feature.
return - 1 ;
}
}
// No match.
return - 1 ;
}
/**
* Checks if the specified client match the team filtering for the specified
* volume .
*
* @ param client The client index .
* @ param volumeIndex The volume to check team filtering on .
* @ return True if client pass the team filtering , false otherwise .
*/
bool : VolTeamFilterMatch ( client , volumeIndex )
{
new VolumeTeamFilters : filter ;
// Chache filter value.
filter = Volumes [ volumeIndex ][ Vol_TeamFilter ];
switch ( filter )
{
case VolTeam_All :
{
// All maches everyone.
return true ;
}
case VolTeam_Humans :
{
// Check if client is a human.
return InfectIsClientHuman ( client );
}
case VolTeam_Zombies :
{
// Check if client is a zombie.
return InfectIsClientInfected ( client );
}
}
// Invalid filter value.
return false ;
}
2009-05-16 01:37:23 +02:00
/**
* Gets wether a client is within volumes or not . Result is stored in a boolean
* array .
*
* @ param client The client index .
* @ param buffer Destination buffer .
* @ param maxlen Size of destination buffer .
* @ return Number of volumes the client is within .
*/
VolGetPlayerStates ( client , bool : buffer [], maxlen )
{
new volumeBuffer [ VolumeAttributes ];
new volCount ;
new Float : volMinBuffer [ 3 ];
new Float : volMaxBuffer [ 3 ];
// Loop through all available volumes.
2009-07-16 10:05:40 +02:00
for ( new volumeIndex = 0 ; volumeIndex < ZR_VOLUMES_MAX && volumeIndex < maxlen ; volumeIndex ++ )
2009-05-16 01:37:23 +02:00
{
2009-07-16 10:05:40 +02:00
if ( VolInUse ( volumeIndex ))
2009-05-16 01:37:23 +02:00
{
// Chache volume to avoid re-indexing.
volumeBuffer = Volumes [ volumeIndex ];
// Get min positions.
2009-07-16 10:05:40 +02:00
volMinBuffer [ 0 ] = volumeBuffer [ Vol_xMin ];
volMinBuffer [ 1 ] = volumeBuffer [ Vol_yMin ];
volMinBuffer [ 2 ] = volumeBuffer [ Vol_zMin ];
2009-05-16 01:37:23 +02:00
// Get max positions.
2009-07-16 10:05:40 +02:00
volMaxBuffer [ 0 ] = volumeBuffer [ Vol_xMax ];
volMaxBuffer [ 1 ] = volumeBuffer [ Vol_yMax ];
volMaxBuffer [ 2 ] = volumeBuffer [ Vol_zMax ];
2009-05-16 01:37:23 +02:00
// Check the cached player location.
2009-07-16 10:05:40 +02:00
if ( IsPointInLocation ( VolPlayerLoc [ client ], volMinBuffer , volMaxBuffer ))
2009-05-16 01:37:23 +02:00
{
// Mark player as in volume.
buffer [ volumeIndex ] = true ;
volCount ++ ;
}
else
{
// Do explicit reset.
buffer [ volumeIndex ] = false ;
}
}
}
return volCount ;
}
2009-07-16 10:05:40 +02:00
/**
* Converts a string into a volumetric feature type .
*
* @ param volType String to convert . Name of type .
* @ return Volumetric feature type or VolFeature_Invalid on error .
*/
VolumeFeatureTypes : VolGetTypeFromString ( const String : volType [])
{
// Check if empty.
if ( strlen ( volType ) == 0 )
{
return VolFeature_Invalid ;
}
// Match types.
if ( StrEqual ( volType , " anticamp " , false ))
{
return VolFeature_Anticamp ;
}
else if ( StrEqual ( volType , " knockback " , false ))
{
return VolFeature_Knockback ;
}
// No match.
return VolFeature_Invalid ;
}
/**
* Converts a volume type to a string .
*
* @ param volType Volume type to convert .
* @ param buffer Destination string buffer .
* @ param maxlen Size of destination buffer .
* @ param shortName Optional . Write short name or human readable name .
* Default is human readable ( false ) .
* @ return Number of cells written .
*/
VolTypeToString ( VolumeFeatureTypes : volType , String : buffer [], maxlen , bool : shortName = false )
{
switch ( volType )
{
case VolFeature_Invalid :
{
return shortName ? strcopy ( buffer , maxlen , " " ) : strcopy ( buffer , maxlen , " (none) " );
}
case VolFeature_Anticamp :
{
return shortName ? strcopy ( buffer , maxlen , " anticamp " ) : strcopy ( buffer , maxlen , " Anti camp " );
}
case VolFeature_Knockback :
{
return shortName ? strcopy ( buffer , maxlen , " knockback " ) : strcopy ( buffer , maxlen , " Knock back modifier " );
}
}
return 0 ;
}
2009-05-16 01:37:23 +02:00
/**
* Callback for update timer . This is the main timer in volumetric features .
*/
public Action : Event_VolUpdateTimer ( Handle : timer )
{
VolUpdatePlayerChanges ();
}
2009-05-30 04:17:01 +02:00
/**
* Callback for trigger delay timer .
*/
public Action : Event_VolTriggerTimer ( Handle : timer )
{
new Float : countDown ;
// Loop through all players.
for ( new client = 1 ; client <= MaxClients ; client ++ )
{
// Loop through all volumes.
for ( new volumeIndex = 0 ; volumeIndex < ZR_VOLUMES_MAX ; volumeIndex ++ )
{
2009-07-16 10:05:40 +02:00
// Check if volume is in use and enabled.
if ( ! VolInUse ( volumeIndex ) || ! VolIsEnabled ( volumeIndex ))
{
// Not in use or enabled, skip volume.
continue ;
}
2009-05-30 04:17:01 +02:00
// Get count down value.
countDown = VolPlayerCountDown [ client ][ volumeIndex ];
// Check if volume trigger delay is enabled.
if ( countDown > 0.0 )
{
// Substract by trigger interval.
countDown -= VolTriggerInterval ;
2009-07-16 10:05:40 +02:00
// Check if time is up.
2009-05-30 04:17:01 +02:00
if ( countDown <= 0.0 )
{
2009-07-16 10:05:40 +02:00
// Update cache.
VolPlayerInVolume [ client ][ volumeIndex ] = true ;
2009-05-30 04:17:01 +02:00
// Trigger volume enter event.
VolOnPlayerEnter ( client , volumeIndex );
// Reset count down value.
VolPlayerCountDown [ client ][ volumeIndex ] = - 1.0 ;
}
2009-07-16 10:05:40 +02:00
// Update count down value and continue.
VolPlayerCountDown [ client ][ volumeIndex ] = countDown ;
2009-05-30 04:17:01 +02:00
}
}
}
}
/**
* Called when zr_vol CVAR is changed .
*/
public VolEnabledChanged ( Handle : cvar , const String : oldvalue [], const String : newvalue [])
{
new bool : isEnabled = bool : StringToInt ( newvalue );
if ( isEnabled )
{
// Volumetric features is enabled.
2009-07-16 10:05:40 +02:00
VolEnable ();
2009-05-30 04:17:01 +02:00
}
else
{
// Volumetric features is disabled.
VolDisable ();
}
}