2009-05-05 06:56:34 +02:00
/*
* ============================================================================
*
2009-07-05 08:49:23 +02:00
* Zombie : Reloaded
2009-05-05 06:56:34 +02:00
*
2009-06-12 05:51:26 +02:00
* File : ztele . inc
* Type : Module
* Description : ZTele handle functions .
*
* 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-05 06:56:34 +02:00
*
* ============================================================================
*/
/**
* Array to store client ' s spawn location .
*/
new Float : g_vecZTeleSpawn [ MAXPLAYERS + 1 ][ 3 ];
/**
* Array to store client ' s current location .
*/
new Float : g_vecZTeleOrigin [ MAXPLAYERS + 1 ][ 3 ];
/**
* Array to store the tele count of each client .
*/
new g_iZTeleCount [ MAXPLAYERS + 1 ];
/**
* Array for storing ZTele timer handles per client .
*/
new Handle : tZTele [ MAXPLAYERS + 1 ];
/**
* Array to store time left before teleport .
*/
new g_iZTeleTimeLeft [ MAXPLAYERS + 1 ];
2009-06-17 23:32:46 +02:00
/**
* Create commands specific to ZTele .
*/
ZTeleOnCommandsCreate ()
{
2009-06-26 02:03:34 +02:00
// Register ZTele command.
2009-06-17 23:32:46 +02:00
RegConsoleCmd ( SAYHOOKS_KEYWORD_ZTELE , ZTeleCommand , " Teleport back to spawn if you are stuck. " );
2009-06-26 02:03:34 +02:00
// Register admin command to force ZTele.
RegAdminCmd ( " zr_ztele_force " , ZTeleForceCommand , ADMFLAG_GENERIC , " Force ZTele on a client. Usage: zr_ztele_force <client> " );
2009-06-17 23:32:46 +02:00
}
2009-05-05 06:56:34 +02:00
/**
* Client is joining the server .
*
* @ param client The client index .
*/
ZTeleClientInit ( client )
{
// Reset timer handle.
tZTele [ client ] = INVALID_HANDLE ;
}
/**
* Client is spawning into the game .
*
* @ param client The client index .
*/
ZTeleOnClientSpawn ( client )
{
// Reset tele count.
g_iZTeleCount [ client ] = 0 ;
// Get spawn location.
GetClientAbsOrigin ( client , g_vecZTeleSpawn [ client ]);
// If timer is running, kill it.
if ( tZTele [ client ] != INVALID_HANDLE )
{
KillTimer ( tZTele [ client ]);
}
// Reset timer handle.
tZTele [ client ] = INVALID_HANDLE ;
}
/**
* Client has been killed .
*
* @ param client The client index .
*/
ZTeleOnClientDeath ( client )
{
// If timer is running, kill it.
if ( tZTele [ client ] != INVALID_HANDLE )
{
KillTimer ( tZTele [ client ]);
}
// Reset timer handle.
tZTele [ client ] = INVALID_HANDLE ;
}
/**
* Player has been infected .
*
* @ param client The client index .
*/
ZTeleOnClientInfected ( client )
{
// If timer is running, kill it.
if ( tZTele [ client ] != INVALID_HANDLE )
{
KillTimer ( tZTele [ client ]);
}
// Reset timer handle.
tZTele [ client ] = INVALID_HANDLE ;
}
/**
* Teleports a client back to spawn if conditions are met .
*
* @ param client The client index .
2009-06-26 02:03:34 +02:00
* @ param force ( Optional ) True to force teleporting of the client , false to follow rules .
* @ param zombie ( Optional ) True to teleport instantly , false to use delay .
2009-05-05 06:56:34 +02:00
* @ return True if teleport was successful , false otherwise .
*/
2009-06-26 02:03:34 +02:00
bool : ZTeleClient ( client , bool : force = false )
2009-05-05 06:56:34 +02:00
{
// If the client is dead, then stop.
if ( ! IsPlayerAlive ( client ))
{
return false ;
}
new bool : infected = InfectIsClientInfected ( client );
// If zombie cvar is disabled and the client is a zombie, then stop.
new bool : ztelezombie = GetConVarBool ( g_hCvarsList [ CVAR_ZTELE_ZOMBIE ]);
2009-06-26 02:03:34 +02:00
if ( ! force && infected && ! ztelezombie )
2009-05-05 06:56:34 +02:00
{
// Tell client they must be human to use this feature.
2009-05-14 09:32:01 +02:00
TranslationPrintToChat ( client , " Must be human " );
2009-05-05 06:56:34 +02:00
return false ;
}
// If zombie has spawned, get before value, get the after value otherwise.
// If the cvar is disabled and the client is a human, then stop.
new bool : ztelehuman = g_bZombieSpawned ? GetConVarBool ( g_hCvarsList [ CVAR_ZTELE_HUMAN_AFTER ]) : GetConVarBool ( g_hCvarsList [ CVAR_ZTELE_HUMAN_BEFORE ]);
2009-06-26 02:03:34 +02:00
if ( ! force && ! infected && ! ztelehuman )
2009-05-05 06:56:34 +02:00
{
// Tell client that feature is restricted at this time.
2009-05-14 09:32:01 +02:00
TranslationPrintToChat ( client , " ZTele restricted human " );
2009-05-05 06:56:34 +02:00
return false ;
}
// If the tele limit has been reached, then stop.
new ztelemax = infected ? GetConVarInt ( g_hCvarsList [ CVAR_ZTELE_MAX_ZOMBIE ]) : GetConVarInt ( g_hCvarsList [ CVAR_ZTELE_MAX_HUMAN ]);
2009-06-26 02:03:34 +02:00
if ( ! force && g_iZTeleCount [ client ] >= ztelemax )
2009-05-05 06:56:34 +02:00
{
// Tell client that they have already reached their limit.
2009-05-14 09:32:01 +02:00
TranslationPrintToChat ( client , " ZTele max " , ztelemax );
2009-05-05 06:56:34 +02:00
return false ;
}
2009-05-06 05:31:48 +02:00
// If teleport is already in progress, then stop.
if ( tZTele [ client ] != INVALID_HANDLE )
{
2009-06-26 02:03:34 +02:00
if ( ! force )
{
TranslationPrintToChat ( client , " ZTele in progress " );
}
2009-05-06 05:31:48 +02:00
return false ;
}
2009-06-26 02:03:34 +02:00
// If we are forcing, then teleport now and stop.
if ( force )
2009-05-05 06:56:34 +02:00
{
2009-06-26 02:03:34 +02:00
// Teleport client to spawn.
ZTeleTeleportClient ( client );
return true ;
2009-05-05 06:56:34 +02:00
}
2009-06-26 02:03:34 +02:00
// Get current location.
GetClientAbsOrigin ( client , g_vecZTeleOrigin [ client ]);
2009-05-05 06:56:34 +02:00
// Set timeleft array to value of respective cvar.
g_iZTeleTimeLeft [ client ] = infected ? GetConVarInt ( g_hCvarsList [ CVAR_ZTELE_DELAY_ZOMBIE ]) : GetConVarInt ( g_hCvarsList [ CVAR_ZTELE_DELAY_HUMAN ]);
if ( g_iZTeleTimeLeft [ client ] > 0 )
{
// Tell client how much time is left until teleport.
2009-05-14 09:32:01 +02:00
TranslationPrintCenterText ( client , " ZTele countdown " , g_iZTeleTimeLeft [ client ]);
2009-05-05 06:56:34 +02:00
2009-05-15 08:14:14 +02:00
// Start timer.
2009-05-05 06:56:34 +02:00
tZTele [ client ] = CreateTimer ( 1.0 , ZTeleTimer , client , TIMER_FLAG_NO_MAPCHANGE | TIMER_REPEAT );
}
else
{
2009-05-15 08:14:14 +02:00
// Teleport client to spawn.
ZTeleTeleportClient ( client );
2009-05-05 06:56:34 +02:00
2009-06-26 02:03:34 +02:00
// If we're forcing the ZTele, then don't increment the count or print how many teleports they have used.
2009-05-05 06:56:34 +02:00
// Tell client they've been teleported.
2009-05-14 09:32:01 +02:00
TranslationPrintCenterText ( client , " ZTele countdown end " , g_iZTeleCount [ client ], ztelemax );
2009-05-05 06:56:34 +02:00
// Increment teleport count.
g_iZTeleCount [ client ] ++ ;
}
return true ;
}
2009-05-15 08:14:14 +02:00
/**
* Teleport client to their spawn location .
*
* @ param client The client index .
*/
ZTeleTeleportClient ( client )
{
// Teleport client.
2009-08-15 19:48:51 +02:00
TeleportEntity ( client , g_vecZTeleSpawn [ client ], NULL_VECTOR , Float : { 0.0 , 0.0 , 0.0 });
2009-05-15 08:14:14 +02:00
}
2009-06-17 23:32:46 +02:00
/**
2009-06-26 02:03:34 +02:00
* Menu callback ( ztele_force )
* Forces ZTele on a client .
*
* @ param menu The menu handle .
* @ param action Action client is doing in menu .
* @ param client The client index .
* @ param slot The menu slot selected . ( starting from 0 )
*/
public ZTeleForceHandle ( Handle : menu_ztele_force , MenuAction : action , client , slot )
{
// Client selected an option.
if ( action == MenuAction_Select )
{
// Get the client index of the selected client.
new target = MenuGetClientIndex ( menu_ztele_force , slot );
// Get the target's name for future use.
decl String : targetname [ MAX_NAME_LENGTH ];
GetClientName ( target , targetname , sizeof ( targetname ));
// Force ZSpawn on the target.
new bool : success = ZTeleClient ( target , true );
// Tell admin the outcome of the action.
if ( success )
{
TranslationReplyToCommand ( client , " ZTele command force successful " , targetname );
}
else
{
TranslationReplyToCommand ( client , " ZTele command force unsuccessful " , targetname );
}
// Re-send the menu.
2009-07-21 22:25:11 +02:00
MenuClientList ( client , ZTeleForceHandle , true , true , false , " ZTele clients title " );
2009-06-26 02:03:34 +02:00
}
// Client closed the menu.
if ( action == MenuAction_Cancel )
{
// Client hit "Back" button.
if ( slot == MenuCancel_ExitBack )
{
// Re-open admin menu.
ZAdminMenu ( client );
}
}
// Client exited menu.
if ( action == MenuAction_End )
{
CloseHandle ( menu_ztele_force );
}
}
/**
* Command callback ( zr_ztele_force )
* Force ZSpawn on a client .
*
* @ param client The client index .
* @ param argc Argument count .
*/
public Action : ZTeleForceCommand ( client , argc )
{
// If not enough arguments given, then stop.
if ( argc < 1 )
{
TranslationReplyToCommand ( client , " ZTele command force syntax " );
return Plugin_Handled ;
}
decl String : target [ MAX_NAME_LENGTH ], String : targetname [ MAX_NAME_LENGTH ];
new targets [ MAXPLAYERS ], bool : tn_is_ml , result ;
// Get targetname.
GetCmdArg ( 1 , target , sizeof ( target ));
// Find a target.
result = ProcessTargetString ( target , client , targets , sizeof ( targets ), COMMAND_FILTER_ALIVE , targetname , sizeof ( targetname ), tn_is_ml );
// Check if there was a problem finding a client.
if ( result <= 0 )
{
ZRReplyToTargetError ( client , result );
return Plugin_Handled ;
}
// x = Client index.
for ( new x = 0 ; x < result ; x ++ )
{
// Give client the item.
new bool : success = ZTeleClient ( targets [ x ], true );
// Tell admin the outcome of the command if only 1 client was targetted.
if ( result == 1 )
{
if ( success )
{
TranslationReplyToCommand ( client , " ZTele command force successful " , targetname );
}
else
{
TranslationReplyToCommand ( client , " ZTele command force unsuccessful " , targetname );
}
}
}
2009-06-26 08:00:57 +02:00
// Log action to game events.
LogEvent ( false , LogType_Normal , LOG_GAME_EVENTS , LogModule_ZTele , " Force ZTele " , " Admin \" %L \" forced player(s) to teleport to spawn. (zr_ztele_force) " , client );
2009-06-26 02:03:34 +02:00
return Plugin_Handled ;
}
/**
* Command callback ( ztele )
2009-06-17 23:32:46 +02:00
* Teleport back to spawn if you are stuck .
*
* @ param client The client index .
* @ param argc Argument count .
*/
public Action : ZTeleCommand ( client , argc )
{
// If client is console, then stop and tell them this feature is for players only.
if ( ZRIsConsole ( client ))
{
TranslationPrintToServer ( " Must be player " );
return Plugin_Handled ;
}
// Start teleportation process.
ZTeleClient ( client );
// This stops the "Unknown command" message in client's console.
return Plugin_Handled ;
}
2009-05-05 06:56:34 +02:00
/**
* Timer callback , counts down teleport to the client .
*
* @ param timer The timer handle .
* @ param client The client index .
*/
public Action : ZTeleTimer ( Handle : timer , any : client )
{
// If client leaves, then stop timer.
if ( ! IsClientInGame ( client ))
{
return Plugin_Stop ;
}
new bool : zteleautocancel = GetConVarBool ( g_hCvarsList [ CVAR_ZTELE_AUTOCANCEL ]);
if ( zteleautocancel )
{
// If client has been running around after using ZTele, then stop timer.
new Float : vecClient [ 3 ];
GetClientAbsOrigin ( client , vecClient );
new Float : distance = GetVectorDistance ( vecClient , g_vecZTeleOrigin [ client ]);
new Float : autocanceldistance = GetConVarFloat ( g_hCvarsList [ CVAR_ZTELE_AUTOCANCEL_DISTANCE ]);
// Convert cvar units
new Float : unitdistance = ZRConvertUnitsFloat ( autocanceldistance , CONVERSION_FEET_TO_UNITS );
// Check if distance has been surpassed.
if ( distance > unitdistance )
{
// Reset timer handle.
tZTele [ client ] = INVALID_HANDLE ;
// Tell client teleport has been cancelled.
2009-05-14 09:32:01 +02:00
TranslationPrintCenterText ( client , " ZTele autocancel centertext " );
TranslationPrintToChat ( client , " ZTele autocancel text " , RoundToNearest ( autocanceldistance ));
2009-05-05 06:56:34 +02:00
// Stop timer.
return Plugin_Stop ;
}
}
// Decrement time left.
g_iZTeleTimeLeft [ client ] -- ;
// Tell client how much time is left until teleport.
2009-05-14 09:32:01 +02:00
TranslationPrintCenterText ( client , " ZTele countdown " , g_iZTeleTimeLeft [ client ]);
2009-05-05 06:56:34 +02:00
// Time has expired.
if ( g_iZTeleTimeLeft [ client ] <= 0 )
{
// Teleport client.
TeleportEntity ( client , g_vecZTeleSpawn [ client ], NULL_VECTOR , NULL_VECTOR );
// Increment teleport count.
g_iZTeleCount [ client ] ++ ;
// Get max teleports per round.
new ztelemax = InfectIsClientInfected ( client ) ? GetConVarInt ( g_hCvarsList [ CVAR_ZTELE_MAX_ZOMBIE ]) : GetConVarInt ( g_hCvarsList [ CVAR_ZTELE_MAX_HUMAN ]);
// Tell client spawn protection is over.
2009-05-14 09:32:01 +02:00
TranslationPrintCenterText ( client , " ZTele countdown end " , g_iZTeleCount [ client ], ztelemax );
2009-05-05 06:56:34 +02:00
// Clear timer handle.
tZTele [ client ] = INVALID_HANDLE ;
// Stop timer.
return Plugin_Stop ;
}
// Allow timer to continue repeating.
return Plugin_Continue ;
2009-06-12 15:52:51 +02:00
}