2009-04-29 01:58:41 +02:00
/*
* ============================================================================
*
* Zombie : Reloaded
*
2009-06-12 05:51:26 +02:00
* File : zspawn . inc
* Type : Module
* Description : Handles zspawn command , spawns late - joining clients into the game .
*
* 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-29 01:58:41 +02:00
*
* ============================================================================
*/
2009-05-06 03:04:55 +02:00
/**
* Global variable to store infect timer handle .
*/
new Handle : tZSpawn = INVALID_HANDLE ;
2009-06-21 07:24:31 +02:00
/**
* Global variable to store SteamID cache handle .
*/
new Handle : g_hZSpawnSteamIDCache = INVALID_HANDLE ;
2009-06-17 23:32:46 +02:00
/**
* Create commands specific to ZSpawn .
*/
ZSpawnOnCommandsCreate ()
{
// Register ZSpawn command.
RegConsoleCmd ( SAYHOOKS_KEYWORD_ZSPAWN , ZSpawnCommand , " Spawn into the game after joining late. " );
2009-06-26 02:03:34 +02:00
// Register admin command to force ZSpawn.
RegAdminCmd ( " zr_zspawn_force " , ZSpawnForceCommand , ADMFLAG_GENERIC , " Force ZSpawn on a client. Usage: zr_zspawn_force <client> ['0' = Spawn as human | '1' = Spawn as zombie] " );
2009-06-17 23:32:46 +02:00
}
2009-05-06 03:04:55 +02:00
/**
* Map is starting .
*/
ZSpawnOnMapStart ()
{
// Reset timer handle.
tZSpawn = INVALID_HANDLE ;
2009-06-21 07:24:31 +02:00
// If SteamID cache hasn't been created yet, then create.
if ( g_hZSpawnSteamIDCache == INVALID_HANDLE )
{
g_hZSpawnSteamIDCache = SteamidCacheCreate ();
}
// Reset the SteamID cache.
SteamidCacheReset ( g_hZSpawnSteamIDCache );
2009-05-06 03:04:55 +02:00
}
2009-04-29 01:58:41 +02:00
/**
* Client is leaving the server .
*
* @ param client The client index .
*/
ZSpawnOnClientDisconnect ( client )
{
2009-05-09 17:45:19 +02:00
// Check if client is a bot.
2009-05-10 01:32:53 +02:00
if ( IsFakeClient ( client ))
2009-05-09 17:45:19 +02:00
{
return ;
}
2009-06-21 07:24:31 +02:00
// Add client to the SteamID cache.
SteamidCacheAddClient ( g_hZSpawnSteamIDCache , client );
2009-04-29 01:58:41 +02:00
}
2009-05-06 03:04:55 +02:00
/**
* Client has been killed .
*
* @ param client The client index .
*/
ZSpawnOnClientDeath ( client )
{
2009-06-21 07:24:31 +02:00
// Add client to the SteamID cache.
SteamidCacheAddClient ( g_hZSpawnSteamIDCache , client );
2009-05-06 03:04:55 +02:00
}
2009-04-29 01:58:41 +02:00
/**
* The round is starting .
*/
ZSpawnOnRoundStart ()
{
2009-06-21 07:24:31 +02:00
// Reset the SteamID cache.
SteamidCacheReset ( g_hZSpawnSteamIDCache );
2009-05-06 03:04:55 +02:00
// If zspawn timer is running, then kill it.
if ( tZSpawn != INVALID_HANDLE )
{
// Kill timer.
KillTimer ( tZSpawn );
// Reset timer handle.
tZSpawn = INVALID_HANDLE ;
}
}
/**
* The freeze time is ending .
*/
ZSpawnOnRoundFreezeEnd ()
{
// If infect timer is running, then kill it.
if ( tZSpawn != INVALID_HANDLE )
{
// Kill timer.
KillTimer ( tZSpawn );
}
// If zspawn is disabled, then stop.
new bool : zspawn = GetConVarBool ( g_hCvarsList [ CVAR_ZSPAWN ]);
if ( ! zspawn )
{
return ;
}
// If timelimit is disabled, then stop.
new bool : zspawntimelimit = GetConVarBool ( g_hCvarsList [ CVAR_ZSPAWN_TIMELIMIT ]);
if ( ! zspawntimelimit )
{
return ;
}
// Get timelimit
new Float : zspawntime = GetConVarFloat ( g_hCvarsList [ CVAR_ZSPAWN_TIMELIMIT_TIME ]);
// Start timer.
tZSpawn = CreateTimer ( zspawntime , ZSpawnTimer , _ , TIMER_FLAG_NO_MAPCHANGE );
}
/**
* The round is ending .
*/
ZSpawnOnRoundEnd ()
{
// If zspawn timer is running, then kill it.
if ( tZSpawn != INVALID_HANDLE )
{
// Kill timer.
KillTimer ( tZSpawn );
// Reset timer handle.
tZSpawn = INVALID_HANDLE ;
}
2009-04-29 01:58:41 +02:00
}
2009-05-06 02:28:09 +02:00
/**
* Spawns a late - joining client into the game .
*
* @ param client The client index .
2009-06-26 02:03:34 +02:00
* @ param force ( Optional ) True to force spawning of the client , false to follow rules .
* @ param zombie ( Optional ) If you are forcing spawn , you must override the team here .
2009-05-06 02:28:09 +02:00
* @ return True if successful , false otherwise .
*/
2009-06-26 02:03:34 +02:00
bool : ZSpawnClient ( client , bool : force = false , bool : zombie = false )
2009-04-29 01:58:41 +02:00
{
// If zspawn is disabled, then stop.
new bool : zspawn = GetConVarBool ( g_hCvarsList [ CVAR_ZSPAWN ]);
2009-06-26 02:03:34 +02:00
if ( ! force && ! zspawn )
2009-04-29 01:58:41 +02:00
{
2009-05-14 09:32:01 +02:00
TranslationPrintToChat ( client , " Feature is disabled " );
2009-05-06 02:28:09 +02:00
return false ;
2009-04-29 01:58:41 +02:00
}
2009-05-06 03:04:55 +02:00
// If client isn't on a team, then stop.
if ( ! ZRIsClientOnTeam ( client ))
{
2009-06-26 02:03:34 +02:00
if ( ! force )
{
// Tell client the command may only be used when on a team.
TranslationPrintToChat ( client , " Must be on team " );
}
2009-05-06 03:04:55 +02:00
return false ;
}
2009-04-29 01:58:41 +02:00
// If client is alive, then stop.
if ( IsPlayerAlive ( client ))
{
2009-06-26 02:03:34 +02:00
if ( ! force )
{
// Tell client the command may only be used when dead.
TranslationPrintToChat ( client , " Must be dead " );
}
2009-05-06 02:28:09 +02:00
return false ;
2009-04-29 01:58:41 +02:00
}
// Block if client has already played during this round.
2009-06-26 02:03:34 +02:00
if ( ! force && SteamidCacheClientExists ( g_hZSpawnSteamIDCache , client ))
2009-04-29 01:58:41 +02:00
{
2009-05-06 02:28:09 +02:00
// Tell client the command may only be used when joining late.
2009-05-14 09:32:01 +02:00
TranslationPrintToChat ( client , " ZSpawn double spawn " );
2009-05-06 02:28:09 +02:00
return false ;
2009-04-29 01:58:41 +02:00
}
2009-06-26 02:03:34 +02:00
new bool : teamzombie ;
2009-06-15 21:43:06 +02:00
2009-06-26 02:03:34 +02:00
if ( ! force )
2009-05-06 03:04:55 +02:00
{
2009-06-26 02:03:34 +02:00
// Check if zspawn override is enabled, and if so get overidden value.
new bool : teamoverride = GetConVarBool ( g_hCvarsList [ CVAR_ZSPAWN_TEAM_OVERRIDE ]);
teamzombie = teamoverride ? GetConVarBool ( g_hCvarsList [ CVAR_ZSPAWN_TEAM_ZOMBIE ]) : GetConVarBool ( g_hCvarsList [ CVAR_RESPAWN_TEAM_ZOMBIE ]);
// Block is the time limit is up.
new bool : zspawntimelimit = GetConVarBool ( g_hCvarsList [ CVAR_ZSPAWN_TIMELIMIT ]);
if ( zspawntimelimit )
2009-05-06 03:04:55 +02:00
{
2009-06-26 02:03:34 +02:00
if ( tZSpawn == INVALID_HANDLE )
2009-06-15 21:43:06 +02:00
{
2009-06-26 02:03:34 +02:00
new zspawntimelimitzombie = GetConVarInt ( g_hCvarsList [ CVAR_ZSPAWN_TIMELIMIT_ZOMBIE ]);
switch ( zspawntimelimitzombie )
2009-06-15 21:43:06 +02:00
{
2009-06-26 02:03:34 +02:00
case - 1 :
{
// Get timelimit
new Float : zspawntime = GetConVarFloat ( g_hCvarsList [ CVAR_ZSPAWN_TIMELIMIT_TIME ]);
// Tell client the timelimit for this command has expired.
TranslationPrintToChat ( client , " ZSpawn timelimit " , RoundToNearest ( zspawntime ));
return false ;
}
case 0 :
{
teamzombie = false ;
}
case 1 :
{
teamzombie = true ;
}
2009-06-15 21:43:06 +02:00
}
}
2009-05-06 03:04:55 +02:00
}
}
2009-06-26 02:03:34 +02:00
else
{
// Use the override team in the function if were forcing the spawn.
teamzombie = zombie ;
}
2009-05-06 03:04:55 +02:00
2009-04-29 01:58:41 +02:00
// Tell respawn module to respawn client.
2009-05-12 04:30:16 +02:00
RespawnSpawnClient ( client , teamzombie );
2009-05-06 02:28:09 +02:00
return true ;
2009-05-01 11:22:45 +02:00
}
2009-05-06 03:04:55 +02:00
2009-06-26 02:03:34 +02:00
/**
* Menu callback ( zspawn_force )
* Forces ZSpawn 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 ZSpawnForceHandle ( Handle : menu_zspawn_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_zspawn_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 = ZSpawnClient ( target , true );
// Tell admin the outcome of the action.
if ( success )
{
TranslationReplyToCommand ( client , " ZSpawn command force successful " , targetname );
}
else
{
TranslationReplyToCommand ( client , " ZSpawn command force unsuccessful " , targetname );
}
// Re-send the menu.
MenuClientList ( client , ZSpawnForceHandle , " ZSpawn clients title " );
}
// 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_zspawn_force );
}
}
2009-06-17 23:32:46 +02:00
/**
* Command callback ( zspawn )
* Spawn into the game after joining late .
*
* @ param client The client index .
* @ param argc Argument count .
*/
public Action : ZSpawnCommand ( 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 ;
}
// Spawn client.
ZSpawnClient ( client );
// This stops the "Unknown command" message in client's console.
return Plugin_Handled ;
}
2009-06-26 02:03:34 +02:00
/**
* Command callback ( zr_zspawn_force )
* Force ZSpawn on a client .
*
* @ param client The client index .
* @ param argc Argument count .
*/
public Action : ZSpawnForceCommand ( client , argc )
{
// If not enough arguments given, then stop.
if ( argc < 1 )
{
TranslationReplyToCommand ( client , " ZSpawn 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_DEAD , targetname , sizeof ( targetname ), tn_is_ml );
// Check if there was a problem finding a client.
if ( result <= 0 )
{
ZRReplyToTargetError ( client , result );
return Plugin_Handled ;
}
// Get item to give to client.
decl String : strZombie [ 4 ];
GetCmdArg ( 2 , strZombie , sizeof ( strZombie ));
// Copy value of second (optional) parameter to 'zombie'.
// It will be false if the parameter wasn't specified.
new bool : zombie = bool : StringToInt ( strZombie );
// x = Client index.
for ( new x = 0 ; x < result ; x ++ )
{
// Give client the item.
new bool : success = ZSpawnClient ( targets [ x ], true , zombie );
// Tell admin the outcome of the command if only 1 client was targetted.
if ( result == 1 )
{
if ( success )
{
TranslationReplyToCommand ( client , " ZSpawn command force successful " , targetname );
}
else
{
TranslationReplyToCommand ( client , " ZSpawn command force unsuccessful " , targetname );
}
}
}
return Plugin_Handled ;
}
2009-05-06 03:04:55 +02:00
/**
* Timer callback , resets handle .
*
* @ param timer The timer handle .
*/
public Action : ZSpawnTimer ( Handle : timer )
{
// Reset timer handle.
tZSpawn = INVALID_HANDLE ;
2009-06-12 15:52:51 +02:00
}