From 9a0db188290af1d15ea5f4a81eeb5bb62db14008 Mon Sep 17 00:00:00 2001
From: ineed bots <ineedbots@pbot.org>
Date: Sun, 10 Dec 2023 05:50:01 -0600
Subject: [PATCH] bot lunge

---
 maps/mp/bots/_bot.gsc                         |  2 +-
 maps/mp/bots/_bot_internal.gsc                | 50 +++++++++++++++++--
 maps/mp/bots/_bot_script.gsc                  |  8 ++-
 maps/mp/bots/_bot_utility.gsc                 | 11 ++++
 ...bots_adapter.gsc => bots_adapter_piw5.gsc} |  6 +++
 5 files changed, 69 insertions(+), 8 deletions(-)
 rename scripts/{bots_adapter.gsc => bots_adapter_piw5.gsc} (80%)

diff --git a/maps/mp/bots/_bot.gsc b/maps/mp/bots/_bot.gsc
index ad8798f..3036fc9 100644
--- a/maps/mp/bots/_bot.gsc
+++ b/maps/mp/bots/_bot.gsc
@@ -150,7 +150,7 @@ init()
 	level.bots_minGrenadeDistance *= level.bots_minGrenadeDistance;
 	level.bots_maxGrenadeDistance = 1024;
 	level.bots_maxGrenadeDistance *= level.bots_maxGrenadeDistance;
-	level.bots_maxKnifeDistance = 80;
+	level.bots_maxKnifeDistance = 128;
 	level.bots_maxKnifeDistance *= level.bots_maxKnifeDistance;
 	level.bots_goalDistance = 27.5;
 	level.bots_goalDistance *= level.bots_goalDistance;
diff --git a/maps/mp/bots/_bot_internal.gsc b/maps/mp/bots/_bot_internal.gsc
index e6592a0..e770b01 100644
--- a/maps/mp/bots/_bot_internal.gsc
+++ b/maps/mp/bots/_bot_internal.gsc
@@ -131,6 +131,7 @@ resetBotVars()
 	self.bot.issmokingafter = false;
 	self.bot.isknifing = false;
 	self.bot.isknifingafter = false;
+	self.bot.knifing_target = undefined;
 
 	self.bot.semi_time = false;
 	self.bot.jump_time = undefined;
@@ -756,7 +757,7 @@ doBotMovement_loop( data )
 	}
 
 	// move!
-	if ( self.bot.wantsprint && self.bot.issprinting )
+	if ( ( self.bot.wantsprint && self.bot.issprinting ) || isDefined( self.bot.knifing_target ) )
 		dir = ( 127, dir[1], 0 );
 
 	self BotBuiltinBotMovement( int( dir[0] ), int( dir[1] ) );
@@ -1643,7 +1644,7 @@ aim_loop()
 				}
 				else
 				{
-					if ( self canAds( dist, curweap ) )
+					if ( self canFire( curweap ) && self isInRange( dist, curweap ) && self canAds( dist, curweap ) )
 					{
 						if ( !self.bot.is_cur_sniper || !self.pers["bots"]["behavior"]["quickscope"] )
 							self thread pressAds();
@@ -1669,7 +1670,9 @@ aim_loop()
 
 					conedot = getConeDot( aimpos, eyePos, angles );
 
-					if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 )
+					if ( isDefined( self.bot.knifing_target ) )
+						self thread bot_lookat( target getTagOrigin( "j_spine4" ), 0.05 );
+					else if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 )
 						self thread bot_lookat( aimpos, 0.05 );
 					else
 						self thread bot_lookat( aimpos, aimspeed, target getVelocity(), true );
@@ -1694,7 +1697,7 @@ aim_loop()
 				if ( ( isplay || target.classname == "misc_turret" ) && !self.bot.isknifingafter && conedot > 0.9 && dist < knifeDist && trace_time > reaction_time && !usingRemote && getDvarInt( "bots_play_knife" ) )
 				{
 					self clear_bot_after_target();
-					self thread knife();
+					self thread knife( target );
 					return;
 				}
 
@@ -2491,16 +2494,53 @@ pressfrag()
 	self BotBuiltinBotAction( "-frag" );
 }
 
+/*
+	Performs melee target
+*/
+do_knife_target( target )
+{
+	self endon( "death" );
+	self endon( "disconnect" );
+	self endon( "bot_knife" );
+
+	if ( !isDefined( target ) || !isPlayer( target ) )
+	{
+		self.bot.knifing_target = undefined;
+		self BotBuiltinBotMeleeParams( 0, 0 );
+		return;
+	}
+
+	dist = distance( target.origin, self.origin );
+
+	if ( dist > getDvarFloat( "aim_automelee_range" ) )
+	{
+		self.bot.knifing_target = undefined;
+		self BotBuiltinBotMeleeParams( 0, 0 );
+		return;
+	}
+
+	self.bot.knifing_target = target;
+
+	self BotBuiltinBotMeleeParams( target getEntityNumber(), dist );
+
+	wait 1;
+
+	self.bot.knifing_target = undefined;
+	self BotBuiltinBotMeleeParams( 0, 0 );
+}
+
 /*
 	Bot will knife.
 */
-knife()
+knife( target )
 {
 	self endon( "death" );
 	self endon( "disconnect" );
 	self notify( "bot_knife" );
 	self endon( "bot_knife" );
 
+	self thread do_knife_target( target );
+
 	self.bot.isknifing = true;
 	self.bot.isknifingafter = true;
 
diff --git a/maps/mp/bots/_bot_script.gsc b/maps/mp/bots/_bot_script.gsc
index 9e2657a..2efd715 100644
--- a/maps/mp/bots/_bot_script.gsc
+++ b/maps/mp/bots/_bot_script.gsc
@@ -4360,7 +4360,7 @@ doReloadCancel()
 */
 bot_weapon_think_loop( data )
 {
-	self waittill_any_timeout( randomIntRange( 2, 4 ), "bot_force_check_switch" );
+	ret = self waittill_any_timeout( randomIntRange( 2, 4 ), "bot_force_check_switch" );
 
 	if ( self BotIsFrozen() )
 		return;
@@ -4399,6 +4399,8 @@ bot_weapon_think_loop( data )
 		return;
 	}
 
+	force = ( ret == "bot_force_check_switch" );
+
 	if ( data.first )
 	{
 		data.first = false;
@@ -4416,6 +4418,8 @@ bot_weapon_think_loop( data )
 			if ( hasTarget )
 				return;
 		}
+		else
+			force = true;
 	}
 
 	weaponslist = self getweaponslistall();
@@ -4426,7 +4430,7 @@ bot_weapon_think_loop( data )
 		weapon = weaponslist[randomInt( weaponslist.size )];
 		weaponslist = array_remove( weaponslist, weapon );
 
-		if ( !self getAmmoCount( weapon ) )
+		if ( !self getAmmoCount( weapon ) && !force )
 			continue;
 
 		if ( !isWeaponPrimary( weapon ) )
diff --git a/maps/mp/bots/_bot_utility.gsc b/maps/mp/bots/_bot_utility.gsc
index aab411b..4f0ff9b 100644
--- a/maps/mp/bots/_bot_utility.gsc
+++ b/maps/mp/bots/_bot_utility.gsc
@@ -112,6 +112,17 @@ BotBuiltinBotMovement( forward, right )
 	}
 }
 
+/*
+	Sets melee params
+*/
+BotBuiltinBotMeleeParams( entNum, dist )
+{
+	if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botmeleeparams"] ) )
+	{
+		self [[ level.bot_builtins["botmeleeparams" ]]]( entNum, dist );
+	}
+}
+
 /*
 	Returns if player is the host
 */
diff --git a/scripts/bots_adapter.gsc b/scripts/bots_adapter_piw5.gsc
similarity index 80%
rename from scripts/bots_adapter.gsc
rename to scripts/bots_adapter_piw5.gsc
index 9b21b0c..2915ed2 100644
--- a/scripts/bots_adapter.gsc
+++ b/scripts/bots_adapter_piw5.gsc
@@ -7,6 +7,7 @@ init()
 	level.bot_builtins["botaction"] = ::do_botaction;
 	level.bot_builtins["botstop"] = ::do_botstop;
 	level.bot_builtins["botmovement"] = ::do_botmovement;
+	level.bot_builtins["botmeleeparams"] = ::do_botmeleeparams;
 }
 
 do_printconsole( s )
@@ -45,3 +46,8 @@ do_botmovement( forward, right )
 {
 	self BotMovement( forward, right );
 }
+
+do_botmeleeparams( entNum, dist )
+{
+	// self BotMeleeParams( entNum, dist );
+}