Code:
#include < amxmodx >
#include < fakemeta >
#if AMXX_VERSION_NUM < 180
#define charsmax(%1) sizeof(%1) - 1
#endif
#if AMXX_VERSION_NUM < 183
#define MAX_PLAYERS 32
#else
// Temp fix until offical 183 is released
#undef MAX_PLAYERS
#define MAX_PLAYERS 32
#endif
#define DEAD_FLAG ( 1 << 0 )
#define OFFSET_TEAM 114
enum
{
CS_TEAM_UNASSIGNED,
CS_TEAM_T,
CS_TEAM_CT,
CS_TEAM_SPECTATOR
}
enum InvisibleData
{
bool:bInvisibleStatus,
nInvisibleTeam,
bool:bInvisibleNotAllowed
}
new g_aInvisible[ MAX_PLAYERS + 1 ][ InvisibleData ];
new g_msgScoreAttrib, g_msgTeamInfo
new g_pCvarPercent;
new bool:g_bRoundEnd;
public plugin_init( )
{
register_plugin( "Invisible Spectator", "0.2", "ConnorMcLeod" )
g_pCvarPercent = register_cvar( "amx_inv_dead_percent", "40" )
g_msgScoreAttrib = get_user_msgid( "ScoreAttrib" )
g_msgTeamInfo = get_user_msgid( "TeamInfo" )
register_message( g_msgScoreAttrib, "msg_ScoreAttrib" );
register_message( g_msgTeamInfo, "msg_TeamInfo" );
register_menucmd( register_menuid( "Team_Select", 1 ), (1<<0)|(1<<1)|(1<<4)|(1<<5), "handle_TeamMenu" );
register_menucmd( register_menuid( "Terrorist_Select", 1 ), 31, "handle_ClassMenu" );
register_menucmd( register_menuid( "CT_Select", 1 ), 31, "handle_ClassMenu" );
register_clcmd( "amx_spectate", "make_invis", ADMIN_RCON );
register_clcmd( "jointeam", "command_joinTeam" );
register_clcmd( "joinclass", "command_joinClass" );
register_logevent( "eRoundEnd", 2, "1=Round_End" )
register_event( "HLTV", "eNewRound", "a", "1=0", "2=0" )
register_event( "ResetHUD", "eResetHUD", "be" )
register_event( "DeathMsg", "eDeathMsg", "a" )
}
public handle_TeamMenu( id, iKey )
{
g_aInvisible[ id ][ bInvisibleNotAllowed ] = true;
}
public handle_ClassMenu( id, iKey )
{
g_aInvisible[ id ][ bInvisibleNotAllowed ] = false;
}
public command_joinClass( id )
{
g_aInvisible[ id ][ bInvisibleNotAllowed ] = false;
}
public command_joinTeam( id )
{
g_aInvisible[ id ][ bInvisibleNotAllowed ] = true;
}
public make_invis( id, level )
{
if( ~get_user_flags( id ) & level )
{
return PLUGIN_CONTINUE;
}
if( g_aInvisible[ id ][ bInvisibleStatus ] )
{
client_print( id, print_console, "You're not invisible anymore" );
g_aInvisible[ id ][ bInvisibleStatus ] = false;
return PLUGIN_HANDLED;
}
if( is_user_alive( id ) )
{
client_print( id, print_console, "You have to be dead first to be an invisible spectator !" )
return PLUGIN_HANDLED;
}
if( g_aInvisible[ id ][ bInvisibleNotAllowed ] )
{
client_print( id, print_console, "You have to finish team choosing first !" )
return PLUGIN_HANDLED;
}
g_aInvisible[ id ][ bInvisibleStatus ] = true;
client_print( id, print_console, "You're now an invisible spectator" );
new nTeam = get_pdata_int( id, OFFSET_TEAM );
if( CS_TEAM_T <= nTeam <= CS_TEAM_CT )
{
g_aInvisible[ id ][ nInvisibleTeam ] = nTeam
set_pdata_int( id, OFFSET_TEAM, CS_TEAM_SPECTATOR );
}
else
{
new aPlayers[ MAX_PLAYERS ], nTerroristNum, nCTNum;
get_players( aPlayers, nTerroristNum, "e", "TERRORIST" );
get_players( aPlayers, nCTNum, "e", "CT" );
g_aInvisible[ id ][ nInvisibleTeam ] = nCTNum > nTerroristNum ? 1 : 2;
}
UTIL_ScoreAttrib( id, 0 );
new szTeamName[ 12 ];
switch( g_aInvisible[ id ][ nInvisibleTeam ] )
{
case 1: formatex( szTeamName, charsmax( szTeamName ), "TERRORIST" );
case 2: formatex( szTeamName, charsmax( szTeamName ), "CT" );
}
UTIL_TeamInfo( id, szTeamName );
return PLUGIN_HANDLED;
}
public eDeathMsg( )
{
if( g_bRoundEnd )
{
return;
}
new aPlayers[ MAX_PLAYERS ], nDead, nNum, nPlayer, Float:flPercent = get_pcvar_float( g_pCvarPercent ) / 100.0;
get_players( aPlayers, nDead, "bh" );
get_players( aPlayers, nNum, "h" );
if( float( nDead ) / float( nNum ) < flPercent )
{
return;
}
for( new i; i < nNum; i++ )
{
nPlayer = aPlayers[ i ]
if( g_aInvisible[ nPlayer ][ bInvisibleStatus ] )
{
UTIL_ScoreAttrib( nPlayer, DEAD_FLAG );
}
}
}
public eNewRound( )
{
g_bRoundEnd = false;
new aPlayers[ MAX_PLAYERS ], nNum, nPlayer;
get_players( aPlayers, nNum );
for( new i; i < nNum; i++ )
{
nPlayer = aPlayers[ i ];
if( g_aInvisible[ nPlayer ][ bInvisibleStatus ] )
{
UTIL_ScoreAttrib( nPlayer, 0 );
}
}
}
public eRoundEnd()
{
g_bRoundEnd = true;
new aPlayers[ MAX_PLAYERS ], nNum, nPlayer;
get_players( aPlayers, nNum );
for( new i; i < nNum; i++ )
{
nPlayer = aPlayers[ i ];
if( g_aInvisible[ nPlayer ][ bInvisibleStatus ] )
{
UTIL_ScoreAttrib( nPlayer, DEAD_FLAG );
}
}
}
public eResetHUD( id )
{
if( g_aInvisible[ id ][ bInvisibleStatus ] )
{
g_aInvisible[ id ][ bInvisibleStatus ] = false;
}
}
// Doesn't seem to work so set flag to 0 at NewRound event.
public msg_ScoreAttrib( msg_type, msg_dest, target )
{
if( !g_aInvisible[ get_msg_arg_int( 1 ) ][ bInvisibleStatus ] )
{
return PLUGIN_CONTINUE;
}
new nFlags = get_msg_arg_int( 2 );
if( nFlags & DEAD_FLAG )
{
set_msg_arg_int( 2, 0, nFlags & ~DEAD_FLAG );
}
return PLUGIN_CONTINUE;
}
public msg_TeamInfo(msg_type, msg_dest, target)
{
new id = get_msg_arg_int( 1 );
if( !g_aInvisible[ id ][ bInvisibleStatus ] )
{
return PLUGIN_CONTINUE;
}
new szTeamName[ 12 ];
get_msg_arg_string( 2, szTeamName, charsmax( szTeamName ) );
if( g_aInvisible[ id ][ nInvisibleTeam ] == CS_TEAM_T && strcmp( szTeamName, "TERRORIST" ) != 0 )
{
set_msg_arg_string( 2, "TERRORIST" );
}
else if( g_aInvisible[ id ][ nInvisibleTeam ] == CS_TEAM_CT && strcmp( szTeamName, "CT" ) != 0 )
{
set_msg_arg_string( 2, "CT" );
}
return PLUGIN_CONTINUE;
}
UTIL_ScoreAttrib( id, nFlags )
{
message_begin( MSG_ALL, g_msgScoreAttrib, _, 0 );
write_byte( id );
write_byte( nFlags );
message_end( );
}
UTIL_TeamInfo( id, szTeamName[ ] )
{
message_begin( MSG_ALL, g_msgTeamInfo, _, 0 );
write_byte( id );
write_string( szTeamName );
message_end( );
}
not to leave from spec.