2020-01-23 23:15:26 +01:00
# pragma semicolon 1
2021-10-17 23:01:05 +02:00
# pragma newdecls required
2020-01-23 23:15:26 +01:00
# define DEBUG
# define PLUGIN_AUTHOR "jenz"
2022-06-01 21:02:41 +02:00
# define PLUGIN_VERSION "1.8"
2020-04-22 00:17:28 +02:00
# define generic_length 256
2020-01-23 23:15:26 +01:00
# include <sourcemod>
# include <sdktools>
2020-07-30 18:01:57 +02:00
# include <sdkhooks>
# include <outputinfo>
2021-10-17 01:09:18 +02:00
# include <cstrike>
2020-06-26 00:11:22 +02:00
# include <socket>
2020-01-23 23:15:26 +01:00
2021-12-14 21:26:29 +01:00
int target_friend_afk_counter [ MAXPLAYERS ] [ MAXPLAYERS + 1 ] ;
2021-12-14 21:01:39 +01:00
int target_friend [ MAXPLAYERS + 1 ] ;
2021-04-05 23:01:54 +02:00
int target_enemy [ MAXPLAYERS + 1 ] ;
2022-07-23 21:14:39 +02:00
bool human_too_close [ MAXPLAYERS + 1 ] ;
bool bot_follow_tp [ MAXPLAYERS + 1 ] ;
2021-04-05 23:01:54 +02:00
int buttons_old [ MAXPLAYERS + 1 ] ;
int flags_old [ MAXPLAYERS + 1 ] ;
2021-10-17 01:09:18 +02:00
int ports [ 7 ] = { 48470 , 48471 , 48472 , 48473 , 48474 , 48479 , 48480 } ; //last three indexes are ports its sending udp from in plugin
2021-12-09 22:49:52 +01:00
int server_ports [ 2 ] = { 27015 , 27035 } ; //server ports: ze, ze2
2020-07-24 00:25:03 +02:00
float client_old_coords [ MAXPLAYERS + 1 ] [ 3 ] ;
2022-07-23 21:14:39 +02:00
float targetfriend_prev_coords [ MAXPLAYERS + 1 ] [ 3 ] ;
2020-09-27 13:57:10 +02:00
bool chat_cooldown = false ;
2020-01-23 23:15:26 +01:00
2020-06-26 00:11:22 +02:00
//socket for bot input
Handle global_socket ;
2022-07-14 21:23:19 +02:00
//timer handle
Handle g_hTimer_pressing = null ;
Handle g_hTimer_bot_connect = null ;
2020-01-23 23:15:26 +01:00
public Plugin myinfo =
{
name = " coordinates for the bot " ,
author = PLUGIN_AUTHOR ,
description = " hello " ,
version = PLUGIN_VERSION ,
url = " "
} ;
2020-02-28 22:00:22 +01:00
public void OnPluginStart ( )
2020-01-23 23:15:26 +01:00
{
2022-07-14 21:23:19 +02:00
for ( int i = 1 ; i < = MaxClients ; i + + )
2022-06-01 21:02:41 +02:00
if ( IsValidClient ( i ) )
2022-07-14 21:23:19 +02:00
{
target_friend [ i ] = 0 ;
target_enemy [ i ] = 0 ;
OnClientPostAdminCheck ( i ) ;
}
//talking
RegConsoleCmd ( " sm_autism " , cmd_talk , " talking to the bot through java application " ) ;
RegConsoleCmd ( " sm_botrtv " , cmd_botrtv , " making bots rtv " ) ;
2022-07-23 21:14:39 +02:00
HookEvent ( " round_start " , Event_RoundStart , EventHookMode_PostNoCopy ) ;
2022-07-14 21:23:19 +02:00
//UDP connection
connect_socket ( ) ;
chat_cooldown = false ;
g_hTimer_bot_connect = CreateTimer ( 15.0 , bot_check_connect , _ , TIMER_REPEAT ) ;
g_hTimer_pressing = CreateTimer ( 0.30 , recursive_pressing , _ , TIMER_REPEAT ) ;
}
public void OnPluginEnd ( )
{
if ( g_hTimer_pressing ! = null )
{
delete g_hTimer_pressing ;
}
if ( g_hTimer_bot_connect ! = null )
{
delete g_hTimer_bot_connect ;
}
2020-01-23 23:15:26 +01:00
}
2022-07-23 21:14:39 +02:00
public void Event_RoundStart ( Handle event , const char [ ] name , bool dontBroadcast )
2020-07-30 18:01:57 +02:00
{
2022-07-23 21:14:39 +02:00
for ( int i = 1 ; i < = MaxClients ; i + + )
2022-06-01 21:02:41 +02:00
{
2022-07-23 21:14:39 +02:00
if ( IsValidClient ( i ) )
{
if ( is_bot_player ( i ) )
{
target_friend [ i ] = - 1 ;
target_enemy [ i ] = - 1 ;
human_too_close [ i ] = false ;
bot_follow_tp [ i ] = false ;
targetfriend_prev_coords [ i ] [ 0 ] = 0.0 ;
targetfriend_prev_coords [ i ] [ 1 ] = 0.0 ;
targetfriend_prev_coords [ i ] [ 2 ] = 0.0 ;
for ( int j = 1 ; j < = MaxClients ; j + + )
{
if ( IsValidClient ( j ) & & j ! = i )
{
target_friend_afk_counter [ i ] [ j ] = 0 ;
}
}
}
}
2022-06-01 21:02:41 +02:00
}
2020-07-30 18:01:57 +02:00
}
2021-07-27 22:55:12 +02:00
public void cmd_talk_help ( int port , int client , char [ ] info )
{
char msg [ generic_length * 5 ] ;
chat_cooldown = true ;
char magic_code [ 16 ] ;
Format ( magic_code , sizeof ( magic_code ) , " 72DqZ84 " ) ;
Format ( msg , sizeof ( msg ) , " clientmessage:%N %s %s " , client , magic_code , info ) ;
send_socket_msg ( msg , strlen ( msg ) , port ) ;
CreateTimer ( 2.0 , bot_chat_cooldown ) ;
}
public bool is_autism_bot1 ( int client )
{
char auth [ 50 ] ;
GetClientAuthId ( client , AuthId_Engine , auth , sizeof ( auth ) ) ;
return StrEqual ( " [U:1:120378081] " , auth , false ) | | StrEqual ( " STEAM_0:1:60189040 " , auth , false ) ;
}
public bool is_autism_bot2 ( int client )
{
char auth [ 50 ] ;
GetClientAuthId ( client , AuthId_Engine , auth , sizeof ( auth ) ) ;
return StrEqual ( " [U:1:1036189204] " , auth , false ) | | StrEqual ( " STEAM_0:0:518094602 " , auth , false ) ;
}
public bool is_autism_bot3 ( int client )
{
char auth [ 50 ] ;
GetClientAuthId ( client , AuthId_Engine , auth , sizeof ( auth ) ) ;
return StrEqual ( " [U:1:408797742] " , auth , false ) | | StrEqual ( " STEAM_0:0:204398871 " , auth , false ) ;
}
public bool is_autism_bot4 ( int client )
{
char auth [ 50 ] ;
GetClientAuthId ( client , AuthId_Engine , auth , sizeof ( auth ) ) ;
return StrEqual ( " [U:1:1221121532] " , auth , false ) | | StrEqual ( " STEAM_0:0:610560766 " , auth , false ) ;
}
2021-08-06 19:16:01 +02:00
public Action cmd_botrtv ( int client , int args )
{
2022-07-14 21:23:19 +02:00
if ( ( CheckCommandAccess ( client , " sm_kick " , ADMFLAG_KICK ) ) | | ( CheckCommandAccess ( client , " sm_reserved " , ADMFLAG_RESERVATION ) ) )
{
2021-08-06 19:16:01 +02:00
for ( int i = 1 ; i < = MaxClients ; i + + )
{
2021-10-17 17:17:34 +02:00
if ( IsValidClient ( i ) & & ! IsFakeClient ( i ) )
2021-08-06 19:16:01 +02:00
{
2021-10-17 23:01:05 +02:00
char msg [ generic_length ] ;
2021-10-17 17:17:34 +02:00
Format ( msg , sizeof ( msg ) , " rtv " ) ;
if ( is_autism_bot1 ( i ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 0 ] ) ;
}
else if ( is_autism_bot2 ( i ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 1 ] ) ;
}
else if ( is_autism_bot3 ( i ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 2 ] ) ;
}
else if ( is_autism_bot4 ( i ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 3 ] ) ;
}
2021-08-06 19:16:01 +02:00
}
}
2022-07-14 21:23:19 +02:00
}
return Plugin_Handled ;
2021-08-06 19:16:01 +02:00
}
2020-05-05 23:52:01 +02:00
public Action cmd_talk ( int client , int args )
2022-07-14 21:23:19 +02:00
{
char info [ generic_length ] ;
GetCmdArgString ( info , sizeof ( info ) ) ;
if ( strlen ( info ) = = 0 )
{
PrintToChat ( client , " Add a message to the command if autism bot is ingame and running on discord " ) ;
return Plugin_Handled ;
}
if ( is_bot_player ( client ) )
{
return Plugin_Handled ;
}
if ( chat_cooldown )
{
PrintToChat ( client , " spamming bot too much, applying cooldown " ) ;
return Plugin_Handled ;
}
bool bot_found = false ;
for ( int i = 1 ; i < = MaxClients ; i + + )
{
if ( IsValidClient ( i ) & & ! IsFakeClient ( i ) )
{
if ( is_autism_bot1 ( i ) )
{
cmd_talk_help ( ports [ 0 ] , client , info ) ;
bot_found = true ;
}
if ( is_autism_bot2 ( i ) )
{
cmd_talk_help ( ports [ 1 ] , client , info ) ;
bot_found = true ;
}
if ( is_autism_bot3 ( i ) )
{
cmd_talk_help ( ports [ 2 ] , client , info ) ;
bot_found = true ;
}
if ( is_autism_bot4 ( i ) )
{
cmd_talk_help ( ports [ 3 ] , client , info ) ;
bot_found = true ;
}
}
}
if ( ! bot_found )
PrintToChat ( client , " bot not connected to server " ) ;
return Plugin_Handled ;
2020-05-05 23:52:01 +02:00
}
2020-09-27 13:57:10 +02:00
public Action bot_chat_cooldown ( Handle timer , any data )
{
chat_cooldown = false ;
return Plugin_Continue ;
}
2020-02-28 22:00:22 +01:00
public void OnMapStart ( )
2020-02-09 00:26:05 +01:00
{
2020-09-27 13:57:10 +02:00
chat_cooldown = false ;
2020-07-24 00:25:03 +02:00
}
2021-07-27 22:55:12 +02:00
public void send_socket_msg ( char [ ] query_msg , int len , int port )
2020-06-09 23:34:49 +02:00
{
2021-07-29 00:59:36 +02:00
//LogMessage("query_msg: %s port: %i", query_msg, port);
2020-06-26 00:11:22 +02:00
if ( global_socket ! = INVALID_HANDLE & & SocketIsConnected ( global_socket ) )
2021-07-27 22:55:12 +02:00
SocketSendTo ( global_socket , query_msg , len , " 127.0.0.1 " , port ) ; //udp
2021-03-27 00:57:40 +01:00
}
2020-06-26 00:11:22 +02:00
public Action bot_check_connect ( Handle timer , any data )
{
2022-07-23 21:14:39 +02:00
//this is designed for being ran from several css servers
int client_count = GetClientCount ( false ) ;
char msg [ generic_length ] ;
int i_port = GetConVarInt ( FindConVar ( " hostport " ) ) ;
bool bot1_connected = false ;
bool bot2_connected = false ;
bool bot3_connected = false ;
bool bot4_connected = false ;
for ( int i = 1 ; i < = MaxClients ; i + + )
if ( IsValidClient ( i ) & & ! IsFakeClient ( i ) )
{
if ( is_autism_bot1 ( i ) )
bot1_connected = true ;
if ( is_autism_bot2 ( i ) )
bot2_connected = true ;
if ( is_autism_bot3 ( i ) )
bot3_connected = true ;
if ( is_autism_bot4 ( i ) )
bot4_connected = true ;
}
2021-12-09 22:49:52 +01:00
2022-07-23 21:14:39 +02:00
if ( i_port = = server_ports [ 0 ] )
{
//revert again to either 10 or 55
int max_allowed_players = 55 ;
if ( client_count > max_allowed_players )
{
Format ( msg , sizeof ( msg ) , " connect to ze2 " ) ;
send_socket_msg ( msg , strlen ( msg ) , ports [ 0 ] ) ;
send_socket_msg ( msg , strlen ( msg ) , ports [ 1 ] ) ;
send_socket_msg ( msg , strlen ( msg ) , ports [ 2 ] ) ;
send_socket_msg ( msg , strlen ( msg ) , ports [ 3 ] ) ;
}
else if ( client_count < 50 )
{
Format ( msg , sizeof ( msg ) , " connect to ze " ) ;
if ( ! bot1_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 0 ] ) ;
if ( ! bot2_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 1 ] ) ;
if ( ! bot3_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 2 ] ) ;
if ( ! bot4_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 3 ] ) ;
}
}
else
{
//in case the bot is not connected to ze2 anymore make sure that is_bot_connected_to_ze2 is set to false again
Format ( msg , sizeof ( msg ) , " not connected to ze2 " ) ;
if ( ! bot1_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 0 ] ) ;
if ( ! bot2_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 1 ] ) ;
if ( ! bot3_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 2 ] ) ;
if ( ! bot4_connected )
send_socket_msg ( msg , strlen ( msg ) , ports [ 3 ] ) ;
}
return Plugin_Continue ;
2020-07-30 18:01:57 +02:00
}
2022-07-27 00:05:08 +02:00
/ *
2020-07-21 01:03:06 +02:00
public void OnPlayerRunCmdPost ( int client , int buttons , int impulse , const float vel [ 3 ] , const float angles [ 3 ] , int weapon , int subtype ,
int cmdnum , int tickcount , int seed , const int mouse [ 2 ] )
{
if ( ! IsClientInGame ( client ) ) return ;
2021-04-09 21:17:30 +02:00
if ( is_bot_player ( client ) )
2020-07-27 19:14:50 +02:00
{
2021-04-06 00:37:47 +02:00
int flags = GetEntityFlags ( client ) ;
2022-07-23 21:14:39 +02:00
if ( ! ( flags & FL_ONGROUND ) & & ( flags_old [ client ] & FL_ONGROUND ) & & ! ( buttons_old [ client ] & IN_JUMP ) & & ! ( buttons & IN_JUMP ) & & ( GetEntityMoveType ( client ) ! = MOVETYPE_LADDER ) & & GetEntProp ( client , Prop_Data , " m_nWaterLevel " ) = = 0 )
2020-07-27 19:14:50 +02:00
{
2021-04-06 00:37:47 +02:00
float Vel [ 3 ] , feet_origin [ 3 ] , ground_pos [ 3 ] , downwards [ 3 ] ;
2021-07-29 13:54:27 +02:00
float velocity_addition_z_axis = 300.0 ; //300.0
2021-04-06 00:37:47 +02:00
GetEntPropVector ( client , Prop_Data , " m_vecVelocity " , Vel ) ;
Vel [ 2 ] + = velocity_addition_z_axis ;
GetClientAbsOrigin ( client , feet_origin ) ;
downwards [ 0 ] = 90.0 ;
downwards [ 1 ] = 0.0 ;
downwards [ 2 ] = 0.0 ;
2021-05-02 02:15:50 +02:00
TR_TraceRayFilter ( feet_origin , downwards , MASK_SOLID , RayType_Infinite , TraceRayDontHitSelf , client ) ;
2021-04-06 00:37:47 +02:00
if ( TR_DidHit ( ) )
2020-10-18 22:54:22 +02:00
{
2021-04-06 00:37:47 +02:00
TR_GetEndPosition ( ground_pos ) ;
feet_origin [ 2 ] - = 10.0 ;
float ground_distance = GetVectorDistance ( feet_origin , ground_pos ) ;
if ( ground_distance > 80 )
2020-10-18 22:54:22 +02:00
{
2021-04-06 00:37:47 +02:00
float angles_eye [ 3 ] ;
GetClientEyeAngles ( client , angles_eye ) ;
2021-04-25 01:01:05 +02:00
//feet_origin[2] += 10.0;
2021-05-02 02:15:50 +02:00
TR_TraceRayFilter ( feet_origin , angles_eye , MASK_SOLID , RayType_Infinite , TraceRayDontHitSelf , client ) ;
2021-04-25 01:01:05 +02:00
if ( TR_DidHit ( ) )
{
TR_GetEndPosition ( ground_pos ) ;
ground_distance = GetVectorDistance ( feet_origin , ground_pos ) ;
float forward_distance = GetVectorDistance ( feet_origin , ground_pos ) ;
2021-04-29 11:55:38 +02:00
if ( forward_distance > 280 )
2021-04-25 01:01:05 +02:00
{
2021-04-26 20:25:40 +02:00
float ClientPos [ 3 ] ;
float Result [ 3 ] ;
GetClientEyePosition ( client , ClientPos ) ;
MakeVectorFromPoints ( ClientPos , ground_pos , Result ) ;
NegateVector ( Result ) ;
GetVectorAngles ( Result , Result ) ;
TeleportEntity ( client , NULL_VECTOR , Result , NULL_VECTOR ) ;
2021-04-27 00:55:50 +02:00
bot_avoid_edge [ client ] = 0 ;
2021-07-29 13:54:27 +02:00
ApplyBoost ( client , 350.0 ) ;
2021-04-25 01:01:05 +02:00
}
}
2020-10-18 22:54:22 +02:00
}
}
2021-07-29 13:54:27 +02:00
//SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", Vel);
TeleportEntity ( client , NULL_VECTOR , NULL_VECTOR , Vel ) ;
2020-07-27 19:14:50 +02:00
}
2021-04-06 00:37:47 +02:00
buttons_old [ client ] = buttons ;
flags_old [ client ] = flags ;
2020-07-27 19:14:50 +02:00
}
2020-07-21 01:03:06 +02:00
}
2022-07-27 00:05:08 +02:00
* /
2020-07-21 01:03:06 +02:00
2021-07-27 22:55:12 +02:00
//this was for turning around to prevent falling off edges
2021-05-02 00:52:51 +02:00
void ApplyBoost ( int client , float amount ) {
2022-07-24 16:03:27 +02:00
float direction [ 3 ] , vel [ 3 ] ;
GetEntPropVector ( client , Prop_Data , " m_vecVelocity " , vel ) ;
NormalizeVector ( vel , direction ) ;
ScaleVector ( direction , amount ) ;
AddVectors ( vel , direction , vel ) ;
TeleportEntity ( client , NULL_VECTOR , NULL_VECTOR , vel ) ;
//SetEntPropVector(client, Prop_Data, "m_vecBaseVelocity", vel);
2021-04-29 11:55:38 +02:00
}
2021-04-09 21:17:30 +02:00
public bool is_bot_player ( int client )
{
2021-07-27 22:55:12 +02:00
return is_autism_bot1 ( client ) | | is_autism_bot2 ( client ) | | is_autism_bot3 ( client ) | | is_autism_bot4 ( client ) ;
2021-04-09 21:17:30 +02:00
}
2020-07-15 02:14:00 +02:00
public Action recursive_pressing ( Handle timer , any data )
2020-06-26 00:11:22 +02:00
{
2022-06-01 21:02:41 +02:00
bool found_valid_ct = false ;
2022-07-27 00:05:08 +02:00
bool found_enemy = false ;
2022-06-01 21:02:41 +02:00
for ( int client = 1 ; client < = MaxClients ; client + + )
{
if ( ! IsValidClient ( client ) ) continue ;
2022-07-27 00:05:08 +02:00
if ( GetClientTeam ( client ) = = 2 & & IsPlayerAlive ( client ) )
{
found_enemy = true ;
}
2022-06-01 21:02:41 +02:00
if ( ! is_bot_player ( client ) & & GetClientTeam ( client ) > 1 )
{
found_valid_ct = true ;
}
}
for ( int client = 1 ; client < = MaxClients ; client + + )
{
if ( ! IsValidClient ( client ) ) continue ;
if ( ! found_valid_ct & & is_bot_player ( client ) )
{
if ( GetClientTeam ( client ) ! = 0 )
ChangeClientTeam ( client , 0 ) ;
continue ;
}
if ( is_bot_player ( client ) )
{
if ( GetClientTeam ( client ) = = 1 | | GetClientTeam ( client ) = = 0 )
{
ChangeClientTeam ( client , 2 ) ;
continue ;
}
if ( IsPlayerAlive ( client ) )
{
int targeteam = 0 ;
if ( GetClientTeam ( client ) ! = 3 )
{
//2 = autismo is zm and should follow enemies sometimes
targeteam = 2 ;
}
else
{
//3 = autismo is human and should follow closest moving ct
targeteam = 3 ;
}
2022-07-23 21:14:39 +02:00
int previous_friend = target_friend [ client ] ;
2022-07-24 16:03:27 +02:00
target_enemy [ client ] = GetClosestClient_option1 ( false , client , 0 ) ;
2022-06-01 21:02:41 +02:00
float enemy_distance = - 1.0 ;
2022-07-24 16:03:27 +02:00
float pos [ 3 ] ;
if ( IsValidClient ( target_enemy [ client ] ) )
{
GetEntPropVector ( target_enemy [ client ] , Prop_Send , " m_vecOrigin " , pos ) ;
enemy_distance = get_power_distance ( client , pos ) ;
}
target_friend [ client ] = GetClosestClient_option1 ( true , client , target_enemy [ client ] ) ;
2022-06-01 21:02:41 +02:00
float dist_target = - 1.0 ;
if ( IsValidClient ( target_friend [ client ] ) )
{
GetEntPropVector ( target_friend [ client ] , Prop_Send , " m_vecOrigin " , pos ) ;
dist_target = get_power_distance ( client , pos ) ;
}
2022-07-24 16:03:27 +02:00
2022-07-23 21:14:39 +02:00
float max_range_dist = 65.0 ;
//here we put into consideration if the human is leaving or standing around. If the bots already catched up to the human they can have a larger distance between the player and themselves so they dont constantly follow him. If the player is leaving the bots needs to follow him much closer.
if ( targeteam = = 3 & & human_too_close [ client ] )
{
max_range_dist = 200.0 ;
}
2022-07-24 16:03:27 +02:00
2022-07-14 21:23:19 +02:00
int state = - 1 ;
2022-07-24 16:03:27 +02:00
//Our previous friend is still an alive human, if we cant see him anymore he went around a corner or teleported
if ( targetfriend_prev_coords [ client ] [ 0 ] ! = 0.0 & & IsValidClient ( previous_friend ) & & GetClientTeam ( previous_friend ) = = GetClientTeam ( client )
& & IsPlayerAlive ( previous_friend ) & & previous_friend ! = target_friend [ client ] )
2022-07-14 21:23:19 +02:00
{
2022-07-24 16:03:27 +02:00
float ClientPos [ 3 ] ;
float friend_prev [ 3 ] ;
GetClientEyePosition ( client , ClientPos ) ;
//if the bot cant see him anymore he around corner or teleported most likley.
//therefore a small distance check should also be needed
float distance_prev_friend_prior = get_power_distance ( previous_friend , targetfriend_prev_coords [ client ] ) ;
GetEntPropVector ( previous_friend , Prop_Send , " m_vecOrigin " , friend_prev ) ;
if ( ! IsPointVisible ( ClientPos , friend_prev ) & & distance_prev_friend_prior > 500.0 )
2022-07-23 21:14:39 +02:00
{
bot_follow_tp [ client ] = true ;
}
}
if ( IsValidClient ( target_friend [ client ] ) & & ! bot_follow_tp [ client ] )
{
GetEntPropVector ( target_friend [ client ] , Prop_Send , " m_vecOrigin " , targetfriend_prev_coords [ client ] ) ;
}
if ( bot_follow_tp [ client ] )
{
float ClientPos [ 3 ] ;
float Result [ 3 ] ;
GetClientEyePosition ( client , ClientPos ) ;
MakeVectorFromPoints ( ClientPos , targetfriend_prev_coords [ client ] , Result ) ;
GetVectorAngles ( Result , Result ) ;
float distance_between_bot_and_tp = get_power_distance ( client , targetfriend_prev_coords [ client ] ) ;
//when we are close enough to teleport just run forward without facing the tp
if ( distance_between_bot_and_tp > 250.0 )
{
TeleportEntity ( client , NULL_VECTOR , Result , NULL_VECTOR ) ;
}
if ( ! IsPointVisible ( ClientPos , targetfriend_prev_coords [ client ] ) )
{
targetfriend_prev_coords [ client ] [ 0 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 1 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 2 ] = 0.0 ;
bot_follow_tp [ client ] = false ;
}
state = 8 ; //if its walking into a TP or up/down a ladder it matters to use +forward;
}
//if the bot or its target is on the ladder just use forward to reach the ladder
else if ( GetEntityMoveType ( client ) = = MOVETYPE_LADDER | | ( IsValidClient ( target_friend [ client ] ) & & GetEntityMoveType ( target_friend [ client ] ) = = MOVETYPE_LADDER ) )
{
if ( IsValidClient ( target_friend [ client ] ) )
{
face_call ( target_friend [ client ] , client ) ;
}
2022-07-14 21:23:19 +02:00
state = 8 ;
}
//if bot is ct: is close enough to friend, can stop following friend and focus on shooting zombies
else if ( targeteam = = 3 & & 0 < dist_target < max_range_dist & & IsValidClient ( target_enemy [ client ] ) )
2022-06-01 21:02:41 +02:00
{
2022-07-23 21:14:39 +02:00
human_too_close [ client ] = true ;
2022-06-01 21:02:41 +02:00
face_call ( target_enemy [ client ] , client ) ;
2022-07-14 21:23:19 +02:00
state = 0 ;
2022-06-01 21:02:41 +02:00
}
2022-07-23 21:14:39 +02:00
//if bot is ct: if bot is not close enough to friend follow him, //dist_target being larger than max_range_dist means a friend was found to follow
2022-07-27 00:05:08 +02:00
//we also check if zm already spawned, if not then stay close to friend
else if ( ( targeteam = = 3 & & dist_target > max_range_dist ) | | ! found_enemy )
2022-07-14 21:23:19 +02:00
{
2022-07-23 21:14:39 +02:00
human_too_close [ client ] = false ;
2022-06-01 21:02:41 +02:00
face_call ( target_friend [ client ] , client ) ;
2022-07-14 21:23:19 +02:00
state = 1 ;
}
2022-07-27 00:05:08 +02:00
//if bot is ct and close enough to friend then just do nothing in case of there being no enemy to shoot at.
2022-07-14 21:23:19 +02:00
else if ( targeteam = = 3 )
{
2022-07-23 21:14:39 +02:00
human_too_close [ client ] = true ;
2022-07-14 21:23:19 +02:00
state = 2 ;
}
//if bot is zm follow enemy sometimes
else if ( targeteam = = 2 & & 0 < enemy_distance < max_range_dist * 5 & & IsValidClient ( target_enemy [ client ] ) )
2022-06-01 21:02:41 +02:00
{
face_call ( target_enemy [ client ] , client ) ;
2022-07-14 21:23:19 +02:00
state = 3 ;
}
//if bot is zm just follow the closest friend zm, but not constantly when too close because people start bitching then
else if ( targeteam = = 2 & & dist_target > max_range_dist / 2 )
{
face_call ( target_friend [ client ] , client ) ;
state = 4 ;
}
//if bot is zm and no close enemies and no friends far away enough to follow then check if friend is close, if its the case then do nothing
else if ( targeteam = = 2 & & 0 < dist_target < max_range_dist / 2 )
{
face_call ( target_friend [ client ] , client ) ;
state = 5 ;
}
//if bot is zm and there are no friends close or far away but there is also no enemy close check if there is an enemy far away
else if ( targeteam = = 2 & & IsValidClient ( target_enemy [ client ] ) )
{
face_call ( target_enemy [ client ] , client ) ;
state = 6 ;
}
//else nothing to do as zm
else if ( targeteam = = 2 )
{
state = 7 ;
2022-06-01 21:02:41 +02:00
}
2022-07-23 21:14:39 +02:00
if ( GetEntProp ( client , Prop_Data , " m_nWaterLevel " ) = = 0 & & GetEntityMoveType ( client ) ! = MOVETYPE_LADDER )
2022-06-01 21:02:41 +02:00
trace_hulling_bot ( client ) ;
char message [ generic_length * 7 ] ;
2022-07-14 21:23:19 +02:00
Format ( message , sizeof ( message ) , " dist_target: %f enemy_distance: %f targeteam: %i state: %i " , dist_target , enemy_distance , targeteam , state ) ;
2022-06-01 21:02:41 +02:00
if ( is_autism_bot1 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 0 ] ) ;
}
if ( is_autism_bot2 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 1 ] ) ;
}
if ( is_autism_bot3 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 2 ] ) ;
}
if ( is_autism_bot4 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 3 ] ) ;
}
}
}
}
found_valid_ct = false ;
for ( int client = 1 ; client < = MaxClients ; client + + )
{
if ( ! IsValidClient ( client ) ) continue ;
if ( ! is_bot_player ( client ) & & GetClientTeam ( client ) = = 3 & & IsPlayerAlive ( client ) )
{
found_valid_ct = true ;
break ;
}
}
if ( ! found_valid_ct )
{
for ( int client = 1 ; client < = MaxClients ; client + + )
{
if ( ! IsValidClient ( client ) ) continue ;
if ( is_bot_player ( client ) & & GetClientTeam ( client ) = = 3 )
{
ForcePlayerSuicide ( client ) ;
}
}
}
return Plugin_Continue ;
2020-01-23 23:15:26 +01:00
}
2020-10-02 19:05:48 +02:00
//https://developer.valvesoftware.com/wiki/Dimensions
2021-03-27 00:57:40 +01:00
public void trace_hulling_bot ( int client )
2020-08-19 00:12:39 +02:00
{
2022-07-23 21:14:39 +02:00
char message [ generic_length * 3 ] ;
float step_cap = 18.0 ;
float crouch_min = 48.0 ;
float stand_min = 63.0 ;
float feet_origin [ 3 ] , mins [ 3 ] , maxs [ 3 ] , eye_position [ 3 ] ;
int BOUNDINGBOX_INFLATION_OFFSET = 3 ;
GetClientEyePosition ( client , eye_position ) ;
GetClientAbsOrigin ( client , feet_origin ) ;
GetClientMins ( client , mins ) ;
GetClientMaxs ( client , maxs ) ;
//increasing boxes sizes
for ( int ij = 0 ; ij < sizeof ( mins ) - 1 ; ij + + )
{
mins [ ij ] - = BOUNDINGBOX_INFLATION_OFFSET ;
maxs [ ij ] + = BOUNDINGBOX_INFLATION_OFFSET ;
}
//acts as full body check
feet_origin [ 2 ] + = BOUNDINGBOX_INFLATION_OFFSET ;
TR_TraceHullFilter ( feet_origin , feet_origin , mins , maxs , MASK_ALL , TraceRayDontHitSelf ) ;
if ( TR_DidHit ( ) )
{
//check 0.0 to 48.0 units starting from feet
feet_origin [ 2 ] - = BOUNDINGBOX_INFLATION_OFFSET ;
mins [ 2 ] = 0.0 ;
maxs [ 2 ] = crouch_min ;
TR_TraceHullFilter ( feet_origin , feet_origin , mins , maxs , MASK_ALL , TraceRayDontHitSelf ) ;
if ( ! ( TR_DidHit ( ) ) )
{
//can crouch
Format ( message , sizeof ( message ) , " hull info:crouch " ) ;
if ( is_autism_bot1 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 0 ] ) ;
}
if ( is_autism_bot2 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 1 ] ) ;
}
if ( is_autism_bot3 ( client ) )
2021-06-18 16:11:42 +02:00
{
2022-07-23 21:14:39 +02:00
send_socket_msg ( message , strlen ( message ) , ports [ 2 ] ) ;
2021-06-18 16:11:42 +02:00
}
2022-07-23 21:14:39 +02:00
if ( is_autism_bot4 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 3 ] ) ;
2021-06-18 16:11:42 +02:00
}
2022-07-23 21:14:39 +02:00
return ;
}
//something blocks floor crouch
eye_position [ 2 ] + = 5.0 ;
TR_TraceHullFilter ( eye_position , eye_position , mins , maxs , MASK_ALL , TraceRayDontHitSelf ) ;
if ( ! ( TR_DidHit ( ) ) )
{
//should not block jump level
Format ( message , sizeof ( message ) , " hull info:jump " ) ;
if ( is_autism_bot1 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 0 ] ) ;
}
if ( is_autism_bot2 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 1 ] ) ;
}
if ( is_autism_bot3 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 2 ] ) ;
}
if ( is_autism_bot4 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 3 ] ) ;
}
return ;
}
else
{
//still potentially crouch hole in wall or one side jumpable
mins [ 2 ] = step_cap ;
float iterator = step_cap ;
while ( iterator < stand_min )
{
maxs [ 2 ] = iterator ;
iterator + = step_cap ;
for ( int jj = 0 ; jj < 2 ; jj + + )
for ( int ij = 0 ; ij < 2 ; ij + + )
{
if ( jj = = 0 )
mins [ ij ] + = BOUNDINGBOX_INFLATION_OFFSET ;
else
maxs [ ij ] - = BOUNDINGBOX_INFLATION_OFFSET ;
float eyes_down [ 3 ] ;
eyes_down [ 0 ] = eye_position [ 0 ] ;
eyes_down [ 1 ] = eye_position [ 1 ] + 10.0 ;
eyes_down [ 2 ] = eye_position [ 2 ] ;
float eyes_forward [ 3 ] ;
eyes_forward [ 0 ] = eye_position [ 0 ] ;
eyes_forward [ 1 ] = eye_position [ 1 ] + 10.0 ;
eyes_forward [ 2 ] = eye_position [ 2 ] ;
float maxs_new [ 3 ] ;
maxs_new [ 0 ] = maxs [ 0 ] - 8.0 ;
maxs_new [ 1 ] = maxs [ 1 ] - 8.0 ;
maxs_new [ 2 ] = maxs [ 2 ] ;
TR_TraceHullFilter ( eye_position , eye_position , mins , maxs_new , MASK_ALL , TraceRayDontHitSelf ) ;
if ( ( TR_DidHit ( ) ) )
2021-06-18 16:11:42 +02:00
{
2022-07-23 21:14:39 +02:00
bool should_jump = true ;
TR_TraceHullFilter ( eyes_down , eyes_forward , mins , maxs , MASK_ALL , TraceRayDontHitSelf ) ;
if ( ! ( TR_DidHit ( ) ) )
{
should_jump = false ;
}
eyes_down [ 0 ] = eye_position [ 0 ] + 10.0 ;
eyes_forward [ 0 ] = eye_position [ 0 ] + 10.0 ;
TR_TraceHullFilter ( eyes_down , eyes_forward , mins , maxs , MASK_ALL , TraceRayDontHitSelf ) ;
if ( ( TR_DidHit ( ) ) )
{
should_jump = false ;
}
if ( should_jump )
{
Format ( message , sizeof ( message ) , " hull info:jump " ) ;
if ( is_autism_bot1 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 0 ] ) ;
}
if ( is_autism_bot2 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 1 ] ) ;
}
if ( is_autism_bot3 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 2 ] ) ;
}
if ( is_autism_bot4 ( client ) )
{
send_socket_msg ( message , strlen ( message ) , ports [ 3 ] ) ;
}
return ;
}
2021-06-18 16:11:42 +02:00
}
2022-07-23 21:14:39 +02:00
TR_TraceHullFilter ( feet_origin , feet_origin , mins , maxs , MASK_ALL , TraceRayDontHitSelf ) ;
if ( ! ( TR_DidHit ( ) ) )
2021-06-18 16:11:42 +02:00
{
2022-07-23 21:14:39 +02:00
//hit wall on one side, no need to jump just run forward
return ;
2021-06-18 16:11:42 +02:00
}
2022-07-23 21:14:39 +02:00
if ( jj = = 0 )
mins [ ij ] - = BOUNDINGBOX_INFLATION_OFFSET ;
else
maxs [ ij ] + = BOUNDINGBOX_INFLATION_OFFSET ;
}
}
//currently detects when two walls meet and create a corner
float move_angles [ 3 ] ;
GetClientEyeAngles ( client , move_angles ) ;
move_angles [ 0 ] = 0.0 ;
move_angles [ 1 ] + = 35.0 ;
move_angles [ 2 ] = 0.0 ;
TeleportEntity ( client , NULL_VECTOR , move_angles , NULL_VECTOR ) ;
return ;
}
}
2020-08-19 00:12:39 +02:00
}
2020-07-27 00:34:15 +02:00
public bool TraceRayDontHitSelf ( int entity , int mask , any data )
{
return entity ! = data & & ! ( 0 < entity < = MaxClients ) ;
}
2021-03-27 00:57:40 +01:00
public void face_call ( int client , int selfclient )
2020-07-24 00:25:03 +02:00
{
2020-07-25 00:50:00 +02:00
for ( int j = 0 ; j < 5 ; j + + )
2021-03-27 00:57:40 +01:00
faceclient ( client , selfclient ) ;
2020-07-21 02:09:41 +02:00
}
2021-03-27 00:57:40 +01:00
public void faceclient ( int target_human , int client )
2020-07-19 00:05:07 +02:00
{
2021-03-27 00:57:40 +01:00
if ( IsValidClient ( client ) & & IsValidClient ( target_human ) )
2020-07-24 00:25:03 +02:00
{
float TargetPos [ 3 ] ;
float ClientPos [ 3 ] ;
float Result [ 3 ] ;
GetClientEyePosition ( target_human , TargetPos ) ;
2021-03-27 00:57:40 +01:00
GetClientEyePosition ( client , ClientPos ) ;
2020-07-24 00:25:03 +02:00
MakeVectorFromPoints ( ClientPos , TargetPos , Result ) ;
GetVectorAngles ( Result , Result ) ;
2021-03-27 00:57:40 +01:00
TeleportEntity ( client , NULL_VECTOR , Result , NULL_VECTOR ) ;
2020-07-24 00:25:03 +02:00
}
2020-07-19 00:05:07 +02:00
}
2020-01-23 23:15:26 +01:00
stock bool IsValidClient ( int client )
{
if ( client > 0 & & client < = MaxClients & & IsClientConnected ( client ) & & IsClientInGame ( client ) )
return true ;
return false ;
}
2021-12-14 21:26:29 +01:00
stock bool is_client_stuck_or_afk ( int client , int i )
2020-09-27 03:16:52 +02:00
{
2022-07-23 21:14:39 +02:00
//triggers between 6-8 times per second
target_friend_afk_counter [ client ] [ i ] + + ;
int human_idle_steps = 12 ;
if ( target_friend_afk_counter [ client ] [ i ] > = human_idle_steps )
{
float min_distance_cap = 1.0 ;
float i_own_distance = get_power_distance ( i , client_old_coords [ i ] ) ;
GetEntPropVector ( i , Prop_Send , " m_vecOrigin " , client_old_coords [ i ] ) ;
bool not_moved = i_own_distance < min_distance_cap ;
if ( ! not_moved )
{
target_friend_afk_counter [ client ] [ i ] = 0 ;
}
return not_moved ;
}
return false ;
2021-07-29 13:20:05 +02:00
}
2022-07-24 16:03:27 +02:00
public int GetClosestClient_option1 ( bool finding_friend , int client , int enemy )
2020-07-19 00:05:07 +02:00
{
2022-07-23 21:14:39 +02:00
float nearestdistance = - 1.0 ;
int nearest = - 1 ;
for ( int i = 1 ; i < = MaxClients ; i + + )
if ( IsValidClient ( i ) & & IsPlayerAlive ( i ) & & i ! = client )
{
if ( ! IsAbleToSee ( client , i ) | | is_client_stuck_or_afk ( client , i ) )
{
continue ;
}
float pos [ 3 ] ;
GetEntPropVector ( i , Prop_Send , " m_vecOrigin " , pos ) ;
float dist_target = get_power_distance ( client , pos ) ;
if ( ( finding_friend & & GetClientTeam ( i ) ! = GetClientTeam ( client ) ) | | ( ! finding_friend & & GetClientTeam ( i ) = = GetClientTeam ( client ) ) )
{
continue ;
}
2022-07-24 16:03:27 +02:00
if ( GetClientTeam ( client ) = = 3 & & IsValidClient ( enemy ) )
{
float enemy_pos [ 3 ] ;
GetEntPropVector ( enemy , Prop_Send , " m_vecOrigin " , enemy_pos ) ;
float enemy_distance = get_power_distance ( i , enemy_pos ) ;
//this should later be an issue at parts where zombies are on all sides around one. having to run close by them.
if ( enemy_distance < = 800.0 )
{
dist_target = 8000000.0 ;
}
}
2022-07-23 21:14:39 +02:00
if ( is_bot_player ( i ) )
{
//just making sure bots have lowest priority
dist_target = 9000000.0 ;
}
if ( nearestdistance < 0 | | dist_target < nearestdistance )
{
nearest = i ;
nearestdistance = dist_target ;
}
}
return nearest ;
2020-07-19 00:05:07 +02:00
}
public float get_power_distance ( int target_player , float [ 3 ] pos )
{
float vec [ 3 ] ;
GetClientAbsOrigin ( target_player , vec ) ;
2020-09-27 03:16:52 +02:00
return GetVectorDistance ( vec , pos ) ;
2020-07-19 00:05:07 +02:00
}
2020-01-23 23:15:26 +01:00
public void OnClientPostAdminCheck ( int client )
{
2022-07-23 21:14:39 +02:00
for ( int i = 1 ; i < = MaxClients ; i + + )
{
if ( IsValidClient ( i ) & & is_bot_player ( i ) & & i ! = client )
{
target_friend_afk_counter [ i ] [ client ] = 0 ;
}
}
//checks if ze or ze2
int i_port = GetConVarInt ( FindConVar ( " hostport " ) ) ;
char msg [ generic_length ] ;
if ( i_port = = server_ports [ 0 ] )
{
Format ( msg , sizeof ( msg ) , " autismo connected to ze " ) ;
}
else
{
Format ( msg , sizeof ( msg ) , " autismo connected to ze2 " ) ;
}
targetfriend_prev_coords [ client ] [ 0 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 1 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 2 ] = 0.0 ;
human_too_close [ client ] = false ;
bot_follow_tp [ client ] = false ;
char auth [ 64 ] ;
GetClientAuthId ( client , AuthId_Engine , auth , sizeof ( auth ) ) ;
if ( is_autism_bot1 ( client ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 0 ] ) ;
}
if ( is_autism_bot2 ( client ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 1 ] ) ;
}
if ( is_autism_bot3 ( client ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 2 ] ) ;
}
if ( is_autism_bot4 ( client ) )
{
send_socket_msg ( msg , strlen ( msg ) , ports [ 3 ] ) ;
}
client_old_coords [ client ] [ 0 ] = 0.0 ;
client_old_coords [ client ] [ 1 ] = 0.0 ;
client_old_coords [ client ] [ 2 ] = 0.0 ;
2020-04-22 00:17:28 +02:00
}
2021-10-17 23:01:05 +02:00
public void OnSocketError ( Handle socket , const int errorType , const int errorNum , any args )
2020-04-22 00:17:28 +02:00
{
2020-09-23 11:48:11 +02:00
CloseHandle ( socket ) ;
LogError ( " [MR] Socket error: %d (errno %d) " , errorType , errorNum ) ;
CreateTimer ( 10.0 , TimerConnect , INVALID_HANDLE , TIMER_HNDL_CLOSE ) ;
2020-04-22 00:17:28 +02:00
}
2020-09-23 11:48:11 +02:00
stock void connect_socket ( )
2020-04-22 00:17:28 +02:00
{
2020-09-23 11:48:11 +02:00
if ( global_socket = = INVALID_HANDLE | | ! SocketIsConnected ( global_socket ) )
{
2021-10-17 01:09:18 +02:00
int i_port = GetConVarInt ( FindConVar ( " hostport " ) ) ;
int target_port = ports [ 4 ] ; //default ze
if ( i_port = = server_ports [ 1 ] )
{
2021-12-09 22:49:52 +01:00
//ze2
2021-10-17 01:09:18 +02:00
target_port = ports [ 5 ] ;
}
2020-09-23 11:48:11 +02:00
//socket otherwise declare in public OnConfigsExecuted(){}
global_socket = SocketCreate ( SOCKET_UDP , OnSocketError ) ;
SocketSetOption ( global_socket , SocketReuseAddr , 1 ) ;
2021-10-17 01:09:18 +02:00
SocketBind ( global_socket , " 127.0.0.0 " , target_port ) ;
SocketConnect ( global_socket , OnSocketConnected , OnSocketReceive , OnSocketDisconnected , " 127.0.0.1 " , target_port ) ; //48474 on ze
2021-04-05 23:01:54 +02:00
}
2020-04-22 00:17:28 +02:00
}
2020-06-26 00:11:22 +02:00
public void OnClientDisconnect ( int client )
2020-04-22 00:17:28 +02:00
{
2022-07-23 21:14:39 +02:00
client_old_coords [ client ] [ 0 ] = 0.0 ;
client_old_coords [ client ] [ 1 ] = 0.0 ;
client_old_coords [ client ] [ 2 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 0 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 1 ] = 0.0 ;
targetfriend_prev_coords [ client ] [ 2 ] = 0.0 ;
human_too_close [ client ] = false ;
bot_follow_tp [ client ] = false ;
for ( int i = 1 ; i < = MaxClients ; i + + )
2022-07-14 21:23:19 +02:00
{
if ( IsValidClient ( i ) & & is_bot_player ( i ) & & i ! = client )
2022-07-23 21:14:39 +02:00
{
2022-07-14 21:23:19 +02:00
target_friend_afk_counter [ i ] [ client ] = 0 ;
2022-07-23 21:14:39 +02:00
}
2022-07-14 21:23:19 +02:00
}
2020-04-22 00:17:28 +02:00
}
2020-06-26 00:11:22 +02:00
//Socket callback
2021-10-17 23:01:05 +02:00
public void OnSocketConnected ( Handle socket , any arg )
2020-04-22 00:17:28 +02:00
{
2020-06-26 00:11:22 +02:00
2020-04-22 00:17:28 +02:00
}
2020-06-26 00:11:22 +02:00
//manage message
2021-10-17 23:01:05 +02:00
public void OnSocketReceive ( Handle socket , char [ ] receiveData , const char dataSize , any hFile )
2020-04-22 00:17:28 +02:00
{
2021-10-17 23:01:05 +02:00
2020-06-26 00:11:22 +02:00
}
2021-10-17 23:01:05 +02:00
public void OnSocketDisconnected ( Handle socket , any arg )
2020-06-26 00:11:22 +02:00
{
2020-09-23 11:48:11 +02:00
CreateTimer ( 10.0 , TimerConnect , INVALID_HANDLE , TIMER_HNDL_CLOSE ) ;
2020-06-09 23:34:49 +02:00
}
2020-06-26 00:11:22 +02:00
public Action TimerConnect ( Handle timer , any arg )
2020-06-09 23:34:49 +02:00
{
2020-09-23 11:48:11 +02:00
connect_socket ( ) ;
2020-06-26 00:11:22 +02:00
return Plugin_Handled ;
2020-07-25 21:15:00 +02:00
}
public bool IsAbleToSee ( int entity , int client )
{
float vecorigin [ 3 ] ;
float vecEyePos [ 3 ] ;
GetClientAbsOrigin ( entity , vecorigin ) ;
GetClientEyePosition ( client , vecEyePos ) ;
// Check if centre is visible.
if ( IsPointVisible ( vecEyePos , vecorigin ) )
return true ;
float vecEyePos_ent [ 3 ] ;
float vecEyeAng [ 3 ] ;
GetClientEyeAngles ( entity , vecEyeAng ) ;
GetClientEyePosition ( entity , vecEyePos_ent ) ;
// Check if weapon tip is visible.
if ( IsFwdVecVisible ( vecEyePos , vecEyeAng , vecEyePos_ent ) )
return true ;
float mins [ 3 ] ;
float maxs [ 3 ] ;
GetClientMins ( client , mins ) ;
GetClientMaxs ( client , maxs ) ;
// Check outer 4 corners of player.
2021-12-14 21:01:39 +01:00
if ( IsRectangleVisible ( vecEyePos , vecorigin , mins , maxs , 1.30 ) ) //1.30
2020-07-25 21:15:00 +02:00
return true ;
// Check inner 4 corners of player.
2021-12-14 21:01:39 +01:00
if ( IsRectangleVisible ( vecEyePos , vecorigin , mins , maxs , 0.65 ) ) //0.65
2020-07-25 21:15:00 +02:00
return true ;
return false ;
}
public bool Filter_NoPlayers ( int entity , int mask )
{
return ( entity > MaxClients & & ! ( 0 < GetEntPropEnt ( entity , Prop_Data , " m_hOwnerEntity " ) < = MaxClients ) ) ;
}
public bool IsPointVisible ( const float start [ 3 ] , const float end [ 3 ] )
{
2021-04-25 01:01:05 +02:00
TR_TraceRayFilter ( start , end , MASK_SOLID , RayType_EndPoint , Filter_NoPlayers ) ;
2020-07-25 21:15:00 +02:00
return TR_GetFraction ( ) = = 1.0 ;
}
public bool IsFwdVecVisible ( const float start [ 3 ] , const float angles [ 3 ] , const float end [ 3 ] )
{
float fwd [ 3 ] ;
GetAngleVectors ( angles , fwd , NULL_VECTOR , NULL_VECTOR ) ;
2021-07-29 13:20:05 +02:00
ScaleVector ( fwd , 50.0 ) ; //ScaleVector(fwd, 50.0);
2020-07-25 21:15:00 +02:00
AddVectors ( end , fwd , fwd ) ;
return IsPointVisible ( start , fwd ) ;
}
public bool IsRectangleVisible ( const float start [ 3 ] , const float end [ 3 ] , const float mins [ 3 ] , const float maxs [ 3 ] , float scale )
{
float ZpozOffset = maxs [ 2 ] ;
float ZnegOffset = mins [ 2 ] ;
float WideOffset = ( ( maxs [ 0 ] - mins [ 0 ] ) + ( maxs [ 1 ] - mins [ 1 ] ) ) / 4.0 ;
// This rectangle is just a point!
if ( ZpozOffset = = 0.0 & & ZnegOffset = = 0.0 & & WideOffset = = 0.0 )
return IsPointVisible ( start , end ) ;
// Adjust to scale.
ZpozOffset * = scale ;
ZnegOffset * = scale ;
WideOffset * = scale ;
// Prepare rotation matrix.
float angles [ 3 ] ;
float fwd [ 3 ] ;
float right [ 3 ] ;
SubtractVectors ( start , end , fwd ) ;
NormalizeVector ( fwd , fwd ) ;
GetVectorAngles ( fwd , angles ) ;
GetAngleVectors ( angles , fwd , right , NULL_VECTOR ) ;
float vRectangle [ 4 ] [ 3 ] ;
float vTemp [ 3 ] ;
// If the player is on the same level as us, we can optimize by only rotating on the z-axis.
if ( FloatAbs ( fwd [ 2 ] ) < = 0.7071 )
{
ScaleVector ( right , WideOffset ) ;
// Corner 1, 2
vTemp = end ;
vTemp [ 2 ] + = ZpozOffset ;
AddVectors ( vTemp , right , vRectangle [ 0 ] ) ;
SubtractVectors ( vTemp , right , vRectangle [ 1 ] ) ;
// Corner 3, 4
vTemp = end ;
vTemp [ 2 ] + = ZnegOffset ;
AddVectors ( vTemp , right , vRectangle [ 2 ] ) ;
SubtractVectors ( vTemp , right , vRectangle [ 3 ] ) ;
}
else if ( fwd [ 2 ] > 0.0 ) // Player is below us.
{
fwd [ 2 ] = 0.0 ;
NormalizeVector ( fwd , fwd ) ;
ScaleVector ( fwd , scale ) ;
ScaleVector ( fwd , WideOffset ) ;
ScaleVector ( right , WideOffset ) ;
// Corner 1
vTemp = end ;
vTemp [ 2 ] + = ZpozOffset ;
AddVectors ( vTemp , right , vTemp ) ;
SubtractVectors ( vTemp , fwd , vRectangle [ 0 ] ) ;
// Corner 2
vTemp = end ;
vTemp [ 2 ] + = ZpozOffset ;
SubtractVectors ( vTemp , right , vTemp ) ;
SubtractVectors ( vTemp , fwd , vRectangle [ 1 ] ) ;
// Corner 3
vTemp = end ;
vTemp [ 2 ] + = ZnegOffset ;
AddVectors ( vTemp , right , vTemp ) ;
AddVectors ( vTemp , fwd , vRectangle [ 2 ] ) ;
// Corner 4
vTemp = end ;
vTemp [ 2 ] + = ZnegOffset ;
SubtractVectors ( vTemp , right , vTemp ) ;
AddVectors ( vTemp , fwd , vRectangle [ 3 ] ) ;
}
else // Player is above us.
{
fwd [ 2 ] = 0.0 ;
NormalizeVector ( fwd , fwd ) ;
ScaleVector ( fwd , scale ) ;
ScaleVector ( fwd , WideOffset ) ;
ScaleVector ( right , WideOffset ) ;
// Corner 1
vTemp = end ;
vTemp [ 2 ] + = ZpozOffset ;
AddVectors ( vTemp , right , vTemp ) ;
AddVectors ( vTemp , fwd , vRectangle [ 0 ] ) ;
// Corner 2
vTemp = end ;
vTemp [ 2 ] + = ZpozOffset ;
SubtractVectors ( vTemp , right , vTemp ) ;
AddVectors ( vTemp , fwd , vRectangle [ 1 ] ) ;
// Corner 3
vTemp = end ;
vTemp [ 2 ] + = ZnegOffset ;
AddVectors ( vTemp , right , vTemp ) ;
SubtractVectors ( vTemp , fwd , vRectangle [ 2 ] ) ;
// Corner 4
vTemp = end ;
vTemp [ 2 ] + = ZnegOffset ;
SubtractVectors ( vTemp , right , vTemp ) ;
SubtractVectors ( vTemp , fwd , vRectangle [ 3 ] ) ;
}
// Run traces on all corners.
2021-10-17 23:01:05 +02:00
for ( int i = 0 ; i < 4 ; i + + )
2020-07-25 21:15:00 +02:00
if ( IsPointVisible ( start , vRectangle [ i ] ) )
return true ;
return false ;
2020-10-18 22:54:22 +02:00
}