From 0e9b680342e58bfc4610e7e323df29e3698382a6 Mon Sep 17 00:00:00 2001
From: jenzur <www.unlozehq@gmail.com>
Date: Fri, 24 Jul 2020 00:25:03 +0200
Subject: [PATCH] further attempts at smoothing the boths movement plus bad
 attempt at handling teleports and some changes to selecting clients to chase

---
 AutismBotIngame/python/ingamefollowct.py     |  51 +++--
 AutismBotIngame/scripting/autism_bot_info.sp | 194 +++++++++++++------
 2 files changed, 169 insertions(+), 76 deletions(-)

diff --git a/AutismBotIngame/python/ingamefollowct.py b/AutismBotIngame/python/ingamefollowct.py
index 2b5969c9..bda78db6 100644
--- a/AutismBotIngame/python/ingamefollowct.py
+++ b/AutismBotIngame/python/ingamefollowct.py
@@ -11,6 +11,7 @@ import codecs
 
 looptestPath = '/home/gameservers/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/cfg/looptest.cfg'
 chatmsg = ""
+ladder_counter = 0
 
 def writeCfgInput(Input):
 	with open(looptestPath, 'w') as f:
@@ -36,10 +37,13 @@ def bot_process_keyinput(input_line):
     movement_input = input_line[input_line.index("keyinput:") + len("keyinput:"):input_line.index("dist_target:")]
     dist_target = input_line[input_line.index("dist_target:") + len("dist_target:"):]
     dist_target = float(dist_target)
-    strInput = f"""{movement_input}; wait 5; """
+    strInput = ""
+    for _ in range(5):
+        strInput += f"""{movement_input}; wait 5; """
+    strInput += "-jump; wait 5; -duck; wait 5;"
     writeCfgInput(strInput)
     print('dist_target: ', dist_target, ' movement strinput: ', strInput)
-    time.sleep(0.1)
+    time.sleep(0.2)
     writeCfgInput("wait 5;")
 
 def bot_process_movement(input_line):
@@ -47,34 +51,49 @@ def bot_process_movement(input_line):
     targethuman = input_line[input_line.index("targethuman:") + len("targethuman:"):input_line.index("bot_on_type:")]
     bot_on_type = input_line[input_line.index("bot_on_type:") + len("bot_on_type:"):input_line.index("enemy_distance:")]
     enemy_distance = input_line[input_line.index("enemy_distance:") + len("enemy_distance:"):input_line.index("bot_stuck:")]
-    bot_stuck = input_line[input_line.index("bot_stuck:") + len("bot_stuck:"):]
+    bot_stuck = input_line[input_line.index("bot_stuck:") + len("bot_stuck:"):input_line.index("targeteam:")]
+    targeteam = input_line[input_line.index("targeteam:") + len("targeteam:"):]
     dist_target = float(dist_target)
     enemy_distance = float(enemy_distance)
     bot_on_type = int(bot_on_type)
     bot_stuck = int(bot_stuck)
-    strInput = ""
-    distance_cap = 2.5 
-    if dist_target < distance_cap and bot_on_type not in [0, 2]:
-        strInput += "-forward; wait 3; -back; wait 3; -moveleft; waii 3; -moveright; wait 3; "
-        print('reduced movement, too close')
-    strInput += "-attack; wait 2; -use; wait 5; -jump; wait 5; -duck; wait 5; +attack; wait 5; cl_minmodels 1; wait 2; +use; "
-
+    targeteam = int(targeteam)
+    strInput = "-attack; wait 2; -use; wait 5; -jump; wait 5; -duck; wait 5; +attack; wait 5; cl_minmodels 1; wait 2; +use; "
     if bot_stuck:
-        strInput += "wait 5; +jump; wait 5; +duck; "
-
-    if bot_on_type == 0:
-        print('bot_on_type ladder ')
+        print('bot stuck')
+        strInput += "+jump; wait 15; +duck; wait 15; -jump; wait 15; -duck; wait 3;"
+    if dist_target > 2.5:
+        strInput += "use weapon_elite; wait 3; "
+    elif targeteam == 3:
+        strInput += "use weapon_p90; wait 3; "
+    elif targeteam == 2:
+        strInput += "use weapon_knife; wait 5; "
+    global ladder_counter
+    if bot_on_type == 0 and ladder_counter < 500:
+        print('bot_on_type ladder, ladder_counter: ', ladder_counter)
         strInput += "setang -90 90 0; wait 5; -back; wait 3; -moveleft; wait 3; -moveright; wait 5; -jump; wait 3; -duck; wait 3; +forward; wait 5;"
+        ladder_counter += 1
     elif bot_on_type == 2:
         print('bot surfing')
         #make some setup to allow surfing/mimic
     else:
+        ladder_counter = 0
+        min_distance_target_human = 2.0
         if bot_on_type == 1:
             print('bot_on_type water')
             strInput += "+jump; wait 5;"
         print('target human: ', targethuman, ' dist_target: ', dist_target, ' enemy distance: ', enemy_distance)
-        strInput += "+forward; wait 5; "
-    
+        if enemy_distance < 0 or dist_target > min_distance_target_human or targeteam == 2:
+            strInput += "+forward; wait 5; "
+            for _ in range(10):
+                boolean_val = random.choice([True, False])
+                if boolean_val:
+                    strInput += "+moveleft; wait 5; -moveleft; wait 5; "
+                else:
+                    strInput += "+moveright; wait 5; -moveright; wait 5; "
+        else:
+            strInput += "-forward; wait 5;"
+        
     #print('strInput final:', strInput)
     writeCfgInput(strInput)
     time.sleep(0.2)
diff --git a/AutismBotIngame/scripting/autism_bot_info.sp b/AutismBotIngame/scripting/autism_bot_info.sp
index 4b7dea9f..bb3d6864 100644
--- a/AutismBotIngame/scripting/autism_bot_info.sp
+++ b/AutismBotIngame/scripting/autism_bot_info.sp
@@ -13,8 +13,12 @@
 //#pragma newdecls required
 int present = 0;
 int targethuman = 0;
-int client_out_balancer[MAXPLAYERS + 1];
 int bot_mini_count_stucker = 0;
+int client_mini_stuck_counter[MAXPLAYERS + 1];
+bool round_start_stuck = false;
+float bot_old_coords[3];
+float client_old_coords[MAXPLAYERS + 1][3];
+bool face_teleporter = false;
 
 //admins & vips
 bool admins[MAXPLAYERS + 1];
@@ -65,15 +69,45 @@ public Action cmd_talk(int client, int args)
 
 public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast)
 {
+	round_start_stuck = false;
+	face_teleporter = false;
 	targethuman = 0;
+	bot_mini_count_stucker = 0;
+	CreateTimer(7.0, permitStuck);
+}
+
+public Action permitStuck(Handle timer, any data)
+{
+	round_start_stuck = true;
+	return Plugin_Continue;
 }
 
 public void OnMapStart()
 {
 	CreateTimer(0.2, recursive_pressing, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
+	CreateTimer(2.0, clients_coordinates, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
 	CreateTimer(10.0, bot_check_connect, INVALID_HANDLE, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
 }
 
+public Action clients_coordinates(Handle timer, any data)
+{
+	if (IsValidClient(present) && IsPlayerAlive(present))
+	{
+		int min_cap = 5;
+		for (int i = 1; i <= MaxClients; i++)
+		if (IsValidClient(i) && IsPlayerAlive(i) && i != present && client_mini_stuck_counter[i] < min_cap)
+			GetEntPropVector(i, Prop_Send, "m_vecOrigin", client_old_coords[i]);
+		if (bot_mini_count_stucker < min_cap)
+			GetEntPropVector(present, Prop_Send, "m_vecOrigin", bot_old_coords);
+		if (face_teleporter)
+			if (IsValidClient(targethuman))
+				face_teleporter = get_power_distance(targethuman, client_old_coords[targethuman]) <= 1.0 ? false : true;
+			else
+				face_teleporter = false;
+	}
+	return Plugin_Continue;
+}
+
 public void send_socket_msg(char[] query_msg, int len)
 {
 	if (global_socket != INVALID_HANDLE && SocketIsConnected(global_socket))
@@ -116,7 +150,7 @@ public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float
 								int cmdnum, int tickcount, int seed, const int mouse[2])
 {
 	if (!IsClientInGame(client)) return;
-	if (client == targethuman)
+	if (client == targethuman && round_start_stuck)
 	{
 		char keyinput[generic_length * 5];
 		if (buttons & IN_JUMP)
@@ -128,7 +162,7 @@ public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float
 			float pos[3];
 			GetEntPropVector(present, Prop_Send, "m_vecOrigin", pos);
 			float dist_target = get_power_distance(targethuman, pos);
-			float dist_cap = 2.0;
+			float dist_cap = 3.0;
 			if (dist_target <= dist_cap)
 			{
 				Format(keyinput, sizeof(keyinput), "keyinput: %s dist_target: %f", keyinput, dist_target);
@@ -159,31 +193,37 @@ public Action recursive_pressing(Handle timer, any data)
 		bool find_closest_match = true;
 		if (IsValidClient(targethuman) && GetClientTeam(targethuman) == targeteam && IsPlayerAlive(targethuman))
 		{
-			float distance_limit = 50.0;
-			if (admins[targethuman])
-				distance_limit = distance_limit * 5;
-			else if (vips[targethuman])
-				distance_limit = distance_limit * 2.5;
 			find_closest_match = is_client_stuck_or_afk(targethuman);
 			if (!find_closest_match)
-			{	
-				float pos[3];
-				GetEntPropVector(present, Prop_Send, "m_vecOrigin", pos);
-				float dist_target = get_power_distance(targethuman, pos);
-				if (!TraceRayable(present, targethuman))
-					dist_target = dist_target * 2;
-				find_closest_match = dist_target < distance_limit ? false : true;
+			{
+				face_call(targethuman);
+				find_closest_match = TraceRayable(present, targethuman) ? false : true;
+				if (find_closest_match)
+				{
+					//check for targethuman entering teleport maybe good enough as this
+					float dist_target = get_power_distance(targethuman, client_old_coords[targethuman]);
+					float min_required_distance = 850.0;
+					if (dist_target > min_required_distance)
+					{
+						find_closest_match = false;
+						face_teleporter = true;
+						float ClientPos[3];
+						float Result[3];
+						GetClientEyePosition(present, ClientPos);
+						MakeVectorFromPoints(ClientPos, client_old_coords[targethuman], Result);
+						GetVectorAngles(Result, Result);
+						TeleportEntity(present, NULL_VECTOR, Result, NULL_VECTOR);
+					}
+				}
 			}
 		}
 		if (find_closest_match)
 			targethuman = GetClosestClient_option1(present, targeteam);
 		if (IsValidClient(targethuman))
-		{	
+		{
 			float pos[3];
 			GetEntPropVector(present, Prop_Send, "m_vecOrigin", pos);
 			float dist_target = get_power_distance(targethuman, pos);
-			int target_enemy = find_closest_enemy(present, targeteam);
-			float enemy_cap = 2.5;
 			float enemy_distance = -1.0;
 			//check ladder = 0, water = 1, in air(surfing) = 2 TODO
 			int bot_on_type = -1;
@@ -195,19 +235,28 @@ public Action recursive_pressing(Handle timer, any data)
 			bool bot_stuck = false;
 			if (bot_on_type != 0 && bot_on_type != 2)
 			{
+				int target_enemy = find_closest_enemy(present, targeteam);
 				if (IsValidClient(target_enemy))
 				{
+					float min_distance_target_human = 2.0;
+					float min_enemy_distance = 100.0;
 					enemy_distance = get_power_distance(target_enemy, pos);
-					if (targeteam == 2)
-						enemy_cap = enemy_cap * 5;
-					if (enemy_distance < enemy_cap)
-						faceclient(target_enemy);
+					//human aiming for zombie
+					if (targeteam == 3 && dist_target < min_distance_target_human && enemy_distance > min_enemy_distance)
+						face_call(target_enemy);
+					//zombie aiming for human
+					else if (targeteam == 2 && min_distance_target_human * min_enemy_distance > enemy_distance && enemy_distance > 0)
+						face_call(target_enemy);
+					//human aiming human && zombie aiming zombie
+					else
+						face_call(targethuman);
 				}
-				if (enemy_distance == -1.0 || enemy_distance > enemy_cap)
-					faceclient(targethuman);
-				bot_stuck = is_bot_stuck();
+				else
+					face_call(targethuman);
+				if (round_start_stuck)
+					bot_stuck = is_bot_stuck();
 			}
-			Format(message, sizeof(message), "dist_target: %f targethuman: %N bot_on_type: %i enemy_distance: %f bot_stuck: %i", dist_target, targethuman, bot_on_type, enemy_distance, bot_stuck);
+			Format(message, sizeof(message), "dist_target: %f targethuman: %N bot_on_type: %i enemy_distance: %f bot_stuck: %i targeteam: %i", dist_target, targethuman, bot_on_type, enemy_distance, bot_stuck, targeteam);
 			send_socket_msg(message, strlen(message));
 		}
 	}
@@ -216,29 +265,36 @@ public Action recursive_pressing(Handle timer, any data)
 
 public bool is_bot_stuck()
 {
-	float flVel[3];
-	GetEntPropVector(present, Prop_Data, "m_vecAbsVelocity", flVel);
-	if (flVel[0] < 10.0 && flVel[1] < 10.0)
+	float min_distance_cap = 2.5;
+	int min_cap = 5;
+	float bot_own_distance = get_power_distance(present, bot_old_coords);
+	if (bot_own_distance < min_distance_cap)
 		bot_mini_count_stucker++;
 	else
-		bot_mini_count_stucker = bot_mini_count_stucker - 3;
-	if (bot_mini_count_stucker > 10)
 		bot_mini_count_stucker = 0;
-	if (bot_mini_count_stucker < 0)
-		bot_mini_count_stucker = 0;
-	return bot_mini_count_stucker > 9;
+	return bot_mini_count_stucker > min_cap;
+}
+
+public void face_call(int client)
+{
+	if (!face_teleporter)
+		for (int j = 0; j < 5; j++)
+			faceclient(client);
 }
 
 public void faceclient(int target_human)
 {
-	float TargetPos[3];
-	float ClientPos[3];
-	float Result[3];
-	GetClientEyePosition(targethuman, TargetPos);
-	GetClientEyePosition(present, ClientPos);
-	MakeVectorFromPoints(ClientPos, TargetPos, Result);
-	GetVectorAngles(Result, Result);
-	TeleportEntity(present, NULL_VECTOR, Result, NULL_VECTOR);
+	if (IsValidClient(present) && IsValidClient(target_human) && GetEntityMoveType(present) != MOVETYPE_LADDER)
+	{
+		float TargetPos[3];
+		float ClientPos[3];
+		float Result[3];
+		GetClientEyePosition(target_human, TargetPos);
+		GetClientEyePosition(present, ClientPos);
+		MakeVectorFromPoints(ClientPos, TargetPos, Result);
+		GetVectorAngles(Result, Result);
+		TeleportEntity(present, NULL_VECTOR, Result, NULL_VECTOR);
+	}
 }
 
 stock bool IsValidClient(int client)
@@ -249,16 +305,15 @@ stock bool IsValidClient(int client)
 }
 
 stock bool is_client_stuck_or_afk(int client)
-{
-	float flVel[3];
-	GetEntPropVector(client, Prop_Data, "m_vecAbsVelocity", flVel);
-	flVel[0] < 10.0 && flVel[1] < 10.0 ? client_out_balancer[client]++ : client_out_balancer[client]--;
-	
-	if (client_out_balancer[client] < -50)
-		client_out_balancer[client] = -50;
-	if (client_out_balancer[client] > 50)
-		client_out_balancer[client] = 50;
-	return client_out_balancer[client] > 25;
+{	
+	float min_distance_cap = 2.0;
+	int min_cap = 5;
+	float client_own_distance = get_power_distance(client, client_old_coords[client]);
+	if (client_own_distance < min_distance_cap)
+		client_mini_stuck_counter[client]++;
+	else
+		client_mini_stuck_counter[client] = 0;
+	return client_mini_stuck_counter[client] > min_cap;
 }
 
 public int find_closest_enemy(int entity, int targeteam)
@@ -271,8 +326,14 @@ public int find_closest_enemy(int entity, int targeteam)
 	if (IsValidClient(i) && IsPlayerAlive(i) && GetClientTeam(i) != targeteam)
 	{
 		float dist_target = get_power_distance(i, pos);
-		if (!TraceRayable(present, i))
-			dist_target = dist_target * dist_target;
+		bool traceable = false;
+		face_call(i);
+		if (TraceRayable(present, i))
+			traceable = true;
+		if (!traceable)
+			continue;
+		if (is_client_stuck_or_afk(i))
+			continue;
 		if (nearestdistance < 0 || dist_target < nearestdistance)
 		{
 			nearest = i;
@@ -293,10 +354,12 @@ public int GetClosestClient_option1(int entity, int targeteam)
 	for (int i = 1; i <= MaxClients; i++)
 	if (IsValidClient(i) && IsPlayerAlive(i) && GetClientTeam(i) == targeteam && i != present)
 	{
-		float dist_target = get_power_distance(i, pos);
 		bool traceable = false;
+		face_call(i);
 		if (TraceRayable(present, i))
 			traceable = true;
+		if (is_client_stuck_or_afk(i))
+			continue;
 		if (admins[i] && traceable)
 		{
 			adminpresent = true;
@@ -316,8 +379,7 @@ public int GetClosestClient_option1(int entity, int targeteam)
 			if (!vips[i])
 				continue;
 		}
-		if (is_client_stuck_or_afk(i))
-			continue;
+		float dist_target = get_power_distance(i, pos);
 		if (!traceable)
 			dist_target = dist_target * dist_target;
 		if (nearestdistance < 0 || dist_target < nearestdistance)
@@ -335,7 +397,7 @@ public float get_power_distance(int target_player, float [3]pos)
 	GetClientAbsOrigin(target_player, vec);
 	float x_axis = Pow(vec[0] - pos[0], 2.0);
 	float y_axis = Pow(vec[1] - pos[1], 2.0);
-	float z_axis = FloatAbs(Pow(vec[2] - pos[2], 1.0));
+	float z_axis = FloatAbs(Pow(vec[2] - pos[2], 3.0));
 	float power_distance = SquareRoot(x_axis * x_axis + y_axis * y_axis + z_axis * z_axis);
 	float defaultcap = 1000.0;
 	return power_distance / defaultcap;
@@ -359,18 +421,27 @@ public void OnClientPostAdminCheck(int client)
 	if (StrEqual("[U:1:120378081]", auth, false))
 	{
 		present = client;
+		bot_old_coords[0] = 0.0;
+		bot_old_coords[1] = 0.0;
+		bot_old_coords[2] = 0.0;
 		bot_send_connected_msg();
 	}
 	else if (StrEqual("STEAM_0:1:60189040", auth, false))
 	{
 		present = client;
+		bot_old_coords[0] = 0.0;
+		bot_old_coords[1] = 0.0;
+		bot_old_coords[2] = 0.0;
 		bot_send_connected_msg();
 	}
 	if (CheckCommandAccess(client, "sm_kick", ADMFLAG_KICK))
 		admins[client] = true;
 	else if (CheckCommandAccess(client, "sm_reserved", ADMFLAG_RESERVATION))
 		vips[client] = true;
-	client_out_balancer[client] = 0;
+	client_old_coords[client][0] = 0.0;
+	client_old_coords[client][1] = 0.0;
+	client_old_coords[client][2] = 0.0;
+	client_mini_stuck_counter[client] = 0;
 }
 
 public OnSocketError(Handle socket, const int errorType, const int errorNum, any args)
@@ -393,7 +464,10 @@ public void OnClientDisconnect(int client)
 	}
 	admins[client] = false;
 	vips[client] = false;
-	client_out_balancer[client] = 0;
+	client_old_coords[client][0] = 0.0;
+	client_old_coords[client][1] = 0.0;
+	client_old_coords[client][2] = 0.0;
+	client_mini_stuck_counter[client] = 0;
 }
 
 public void bot_send_connected_msg()