This version is much better than the original and includes ignore weapons.
Original: Both players need to be looking at each other for threshold seconds for a punishment to happen to both.
New: Detection is done at individual player level so if player A can see player B, regardless of where player B is looking, player A will get punished after the threshold seconds. The seconds counter is reset to 0 if player A looks away or if player A switches to an ignore weapon (knife, c4, smoke, flashbang).
Edit: Applied a small fix for something I accidentally left in there from the previous version.
Edit2: Will now display multiple enemy names if the player was looking at multiple players which resulted in him being killed. "* Killed bugsy for No-Killing [ bot1, bot2, bot3 ]". Also increased the entity next-think from 0.1 to 1.0 which is more efficient.
PHP Code:
#include <amxmodx>
#include <cstrike>
#include <engine>
#include <fakemeta>
#include <fun>
new const Version[] = "0.3";
#define TESTING
#define MAX_PLAYERS 32
new g_ThinkingEntity;
new g_LastEyeContact[ MAX_PLAYERS + 1 ][ MAX_PLAYERS + 1 ];
new g_pSightThreshold;
const Ignore_Weapons = ( ( 1 << CSW_KNIFE ) | ( 1 << CSW_FLASHBANG ) | ( 1 << CSW_SMOKEGRENADE ) | ( 1 << CSW_C4 ) );
public plugin_init()
{
register_plugin( "No-Kill Punishment" , Version , "bugsy" );
register_event( "DeathMsg" , "EventDeathMsg" , "a" );
g_pSightThreshold = register_cvar( "nkp_sightthresholdseconds" , "10" );
CreateEntity();
}
public client_disconnect( id )
{
ResetPlayer( id );
}
public EventDeathMsg()
{
ResetPlayer( read_data( 2 ) );
}
public ViewEntity_Think( iEntity )
{
new iPlayers[ 32 ] , iNum , Float:fOrigin[ 3 ] , Float:fEnemyOrigin[ 3 ] , iPlayer , iEnemy, szName[ 32 ] , szEnemyName[ 32 * 6 ] , iPos, iThresholdSeconds , iSysTime;
get_players( iPlayers , iNum , "a" );
if ( iNum )
{
for ( new i = 0 ; i < iNum ; i++ )
{
iPlayer = iPlayers[ i ];
for ( new p = 0 ; p < iNum ; p++ )
{
iEnemy = iPlayers[ p ];
#if defined TESTING
//While testing this will force bots on the opposite team to only have and hold the glock.
//If this is made an ignore weapon then you must change this to a different weapon.
if ( is_user_bot( iEnemy ) && ( get_user_weapon( iEnemy ) != CSW_GLOCK18 ) )
{
strip_user_weapons( iEnemy );
give_item( iEnemy , "weapon_glock" );
client_cmd( iEnemy , "slot2;+attack;wait;-attack" );
}
#endif
if ( ( iPlayer != iEnemy ) && ( cs_get_user_team( iPlayer ) != cs_get_user_team( iEnemy ) ) )
{
entity_get_vector( iEnemy , EV_VEC_origin , fEnemyOrigin );
if ( !( Ignore_Weapons & ( 1 << get_user_weapon( iPlayer ) ) ) && is_in_viewcone( iPlayer , fEnemyOrigin ) )
{
entity_get_vector( iPlayer , EV_VEC_origin , fOrigin );
if ( IsInLineOfSight( fOrigin , fEnemyOrigin ) )
{
if ( !g_LastEyeContact[ iPlayer ][ iEnemy ] )
{
g_LastEyeContact[ iPlayer ][ iEnemy ] = get_systime();
}
#if defined TESTING
else
{
get_user_name( iPlayer , szName , charsmax( szName ) );
get_user_name( iEnemy , szEnemyName , charsmax( szEnemyName ) );
client_print( 0 , print_chat , "%s CAN SEE %s - %d SECONDS" , szName , szEnemyName , ( get_systime() - g_LastEyeContact[ iPlayer ][ iEnemy ] ) );
}
#endif
}
#if defined TESTING
else
{
if ( g_LastEyeContact[ iPlayer ][ iEnemy ] )
{
get_user_name( iPlayer , szName , charsmax( szName ) );
get_user_name( iEnemy , szEnemyName , charsmax( szEnemyName ) );
client_print( 0 , print_chat , "%s NO LONGER LOOKING AT %s" , szName , szEnemyName );
g_LastEyeContact[ iPlayer ][ iEnemy ] = 0;
}
}
#endif
}
else
{
#if defined TESTING
if ( g_LastEyeContact[ iPlayer ][ iEnemy ] )
{
get_user_name( iPlayer , szName , charsmax( szName ) );
get_user_name( iEnemy , szEnemyName , charsmax( szEnemyName ) );
client_print( iPlayer , print_chat , "%s NO LONGER LOOKING AT %s" , szName , szEnemyName );
}
#endif
g_LastEyeContact[ iPlayer ][ iEnemy ] = 0;
}
}
}
}
iSysTime = get_systime();
iThresholdSeconds = get_pcvar_num( g_pSightThreshold );
for ( new i = 0 ; i < iNum ; i++ )
{
iPlayer = iPlayers[ i ];
iPos = 0;
for ( new p = 0 ; p < iNum ; p++ )
{
iEnemy = iPlayers[ p ];
if ( ( iPlayer != iEnemy ) && g_LastEyeContact[ iPlayer ][ iEnemy ] && ( ( iSysTime - g_LastEyeContact[ iPlayer ][ iEnemy ] ) >= iThresholdSeconds ) )
{
iPos += get_user_name( iEnemy , szEnemyName[ iPos ] , charsmax( szEnemyName ) - iPos );
iPos += copy( szEnemyName[ iPos ] , charsmax( szEnemyName ) - iPos , ", " );
g_LastEyeContact[ iPlayer ][ iEnemy ] = 0;
}
}
if ( iPos )
{
get_user_name( iPlayer , szName , charsmax( szName ) );
user_kill( iPlayer );
szEnemyName[ iPos - 2 ] = EOS;
client_print( 0 , print_chat , "* Killed %s for No-Killing [ %s ] !" , szName , szEnemyName );
}
}
}
entity_set_float( g_ThinkingEntity , EV_FL_nextthink , get_gametime() + 1.0 );
}
bool:IsInLineOfSight( Float:fOrigin1[ 3 ] , Float:fOrigin2[ 3 ] )
{
new iTrace , Float:fFraction;
engfunc( EngFunc_TraceLine , fOrigin1 , fOrigin2 , IGNORE_MONSTERS , 0 , iTrace );
get_tr2( iTrace , TR_flFraction , fFraction );
return bool:( fFraction == 1.0 );
}
ResetPlayer( id )
{
arrayset( g_LastEyeContact[ id ] , 0 , sizeof( g_LastEyeContact[] ) );
}
CreateEntity()
{
g_ThinkingEntity = create_entity( "info_target" );
entity_set_string( g_ThinkingEntity , EV_SZ_classname , "view_entity" );
register_think( "view_entity" , "ViewEntity_Think" );
entity_set_float( g_ThinkingEntity , EV_FL_nextthink , get_gametime() + 1.0 );
}
__________________