PHP Code:
/*
- Credits:
# Alucard (Get_origin)
# Black Rose (Check buttoms)
# bugsy (added functionality, code cleanup, fixes and added cvars)
*/
#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <cstrike>
#if !defined MAX_PLAYERS
const MAX_PLAYERS = 32;
#endif
new const Version[] = "0.3";
const RespawnButtons = ( IN_DUCK | IN_USE );
enum CPRData
{
Float:CorpseOrigin[ 3 ],
ReviverID
}
new g_rdData[ MAX_PLAYERS + 1 ][ CPRData ];
new g_msgBarTime;
new g_pDistance , g_gReviveSeconds;
public plugin_init()
{
register_plugin( "CPR Revive" , Version , "Alu-rose-sy" );
register_event( "DeathMsg" , "DeathMsg" , "a" , "1>0" );
register_forward( FM_CmdStart , "CmdStart" );
g_msgBarTime = get_user_msgid( "BarTime" );
g_pDistance = register_cvar( "cpr_distance" , "50" );
g_gReviveSeconds = register_cvar( "cpr_reviveseconds" , "10" );
}
public DeathMsg()
{
new iVictim = read_data( 2 );
pev( iVictim , pev_origin , g_rdData[ iVictim ][ CorpseOrigin ] );
}
public CmdStart( id , uc_handle , seed )
{
if ( !is_user_alive( id ) )
return;
static iRespawnID , bool:bRespawning[ MAX_PLAYERS + 1 ] , bBarStarted[ MAX_PLAYERS + 1 ] , Float:fOrigin[ 3 ];
if ( ( get_uc( uc_handle , UC_Buttons ) & RespawnButtons ) == RespawnButtons )
{
if ( !bRespawning[ id ] )
{
if ( ( iRespawnID = CheckOrigin( id ) ) )
{
g_rdData[ iRespawnID ][ ReviverID ] = id;
set_pev( id , pev_iuser2 , iRespawnID );
set_task( get_pcvar_float( g_gReviveSeconds ) , "RevivePlayer" , iRespawnID );
bRespawning[ id ] = true;
if ( !bBarStarted[ id ] )
{
StartBar( id );
bBarStarted[ id ] = true;
}
}
}
else
{
pev( id , pev_origin , fOrigin );
iRespawnID = pev( id , pev_iuser2 );
if ( get_distance_f_x( fOrigin , g_rdData[ iRespawnID ][ CorpseOrigin ] ) > get_pcvar_float( g_pDistance ) )
{
remove_task( iRespawnID );
StopBar( id );
bRespawning[ id ] = false;
bBarStarted[ id ] = false;
if ( !is_user_alive( iRespawnID ) )
client_print( id , print_chat , "* You moved too far away from player to revive" );
set_pev( id , pev_iuser2 , 0 );
}
}
}
else if ( bRespawning[ id ] )
{
StopBar( id );
remove_task( iRespawnID );
bRespawning[ id ] = false;
bBarStarted[ id ] = false;
}
return;
}
public CheckOrigin( id )
{
new iPlayers[ 32 ] , iNum , Float:fOrigin[ 3 ] , Float:fDistanceThreshold , Float:fDistance , iNearestPlayer , iPlayer , Float:fNearestDistance;
pev( id , pev_origin , fOrigin );
get_players( iPlayers , iNum , "be" , cs_get_user_team( id ) == CS_TEAM_T ? "TERRORIST" : "CT" );
fDistanceThreshold = get_pcvar_float( g_pDistance );
for ( new i = 0 ; i < iNum ; i++ )
{
iPlayer = iPlayers[ i ];
fDistance = get_distance_f_x( fOrigin , g_rdData[ iPlayer ][ CorpseOrigin ] );
if ( !fNearestDistance || ( fNearestDistance && ( fDistance < fNearestDistance ) ) )
{
fNearestDistance = fDistance;
iNearestPlayer = iPlayer;
}
}
return ( fNearestDistance <= fDistanceThreshold ) ? iNearestPlayer : 0;
}
public RevivePlayer( id )
{
new szRespawnName[ 33 ] , szRespawnerName[ 33 ];
get_user_name( id , szRespawnName , charsmax( szRespawnName ) );
get_user_name( g_rdData[ id ][ ReviverID ] , szRespawnerName , charsmax( szRespawnerName ) );
ExecuteHamB( Ham_CS_RoundRespawn , id );
set_pev( id , pev_origin , g_rdData[ id ][ CorpseOrigin ] );
client_print( 0 , print_chat , "[CPR] User %s respawned target %s" , szRespawnerName , szRespawnName );
}
public StartBar( id )
{
message_begin( MSG_ONE , g_msgBarTime , {0,0,0} , id );
write_short( get_pcvar_num( g_gReviveSeconds ) );
message_end();
}
public StopBar( id )
{
message_begin( MSG_ONE , g_msgBarTime , _, id );
write_short( 0 );
message_end();
}
//Workaround due to AMX-X compile error using array from enumerator in get_distance_f()
Float:get_distance_f_x( Float:fOrigin1[] , Float:fOrigin2[] )
{
new Float:f1[ 3 ] , Float:f2[3];
f1[0] = fOrigin1[0];
f1[1] = fOrigin1[1];
f1[2] = fOrigin1[2];
f2[0] = fOrigin2[0];
f2[1] = fOrigin2[1];
f2[2] = fOrigin2[2];
return get_distance_f( f1 , f2 );
}