diff --git a/maps/mp/bots/_bot.gsc b/maps/mp/bots/_bot.gsc index 7c7ce2b..cad8bcc 100644 --- a/maps/mp/bots/_bot.gsc +++ b/maps/mp/bots/_bot.gsc @@ -145,7 +145,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 d41bfaa..241c166 100644 --- a/maps/mp/bots/_bot_internal.gsc +++ b/maps/mp/bots/_bot_internal.gsc @@ -150,6 +150,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; @@ -395,7 +396,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] ) ); @@ -1351,7 +1352,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(); @@ -1380,7 +1381,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 ); @@ -1394,13 +1397,16 @@ aim_loop() conedot = getConeDot( aimpos, eyePos, angles ); - self thread bot_lookat( aimpos, aimspeed ); + if ( conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 ) + self thread bot_lookat( aimpos, 0.05 ); + else + self thread bot_lookat( aimpos, aimspeed ); } if ( isplay && !self.bot.isknifingafter && conedot > 0.9 && dist < level.bots_maxKnifeDistance && trace_time > reaction_time && getDvarInt( "bots_play_knife" ) ) { self clear_bot_after_target(); - self thread knife(); + self thread knife( target ); return; } @@ -2125,16 +2131,54 @@ sprint() self BotBuiltinBotAction( "-sprint" ); } +/* + 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; + + angles = VectorToAngles( target.origin - self.origin ); + self BotBuiltinBotMeleeParams( angles[1], 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 a5b30b5..f72fd34 100644 --- a/maps/mp/bots/_bot_script.gsc +++ b/maps/mp/bots/_bot_script.gsc @@ -2292,7 +2292,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; @@ -2316,6 +2316,8 @@ bot_weapon_think_loop( data ) } } + force = ( ret == "bot_force_check_switch" ); + if ( data.first ) { data.first = false; @@ -2333,6 +2335,8 @@ bot_weapon_think_loop( data ) if ( hasTarget ) return; } + else + force = true; } weaponslist = self getweaponslist(); @@ -2343,7 +2347,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 ( maps\mp\gametypes\_weapons::isHackWeapon( weapon ) ) diff --git a/maps/mp/bots/_bot_utility.gsc b/maps/mp/bots/_bot_utility.gsc index f4978f7..393484a 100644 --- a/maps/mp/bots/_bot_utility.gsc +++ b/maps/mp/bots/_bot_utility.gsc @@ -116,6 +116,17 @@ BotBuiltinBotMoveTo( where ) } } +/* + Sets melee params +*/ +BotBuiltinBotMeleeParams( yaw, dist ) +{ + if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botmeleeparams"] ) ) + { + self [[ level.bot_builtins["botmeleeparams" ]]]( yaw, dist ); + } +} + /* Test if is a bot */ diff --git a/maps/mp/gametypes/_callbacksetup.gsx b/maps/mp/gametypes/_callbacksetup.gsx index 55d5c04..f3d0ae3 100644 --- a/maps/mp/gametypes/_callbacksetup.gsx +++ b/maps/mp/gametypes/_callbacksetup.gsx @@ -17,7 +17,7 @@ CodeCallback_StartGameType() level.gametypestarted = true; // so we know that the gametype has been started up - level thread scripts\bots_adapter::init(); + level thread scripts\bots_adapter_cod4x::init(); level thread scripts\bots_chat::init(); level thread scripts\bots_menu::init(); level thread scripts\bots_wp_editor::init(); diff --git a/scripts/bots_adapter.gsc b/scripts/bots_adapter_cod4x.gsc similarity index 61% rename from scripts/bots_adapter.gsc rename to scripts/bots_adapter_cod4x.gsc index f68d39a..9b87d54 100644 --- a/scripts/bots_adapter.gsc +++ b/scripts/bots_adapter_cod4x.gsc @@ -1,13 +1,12 @@ init() { level.bot_builtins["printconsole"] = ::do_printconsole; - level.bot_builtins["filewrite"] = ::do_filewrite; - level.bot_builtins["fileread"] = ::do_fileread; level.bot_builtins["fileexists"] = ::do_fileexists; level.bot_builtins["botaction"] = ::do_botaction; level.bot_builtins["botstop"] = ::do_botstop; level.bot_builtins["botmovement"] = ::do_botmovement; level.bot_builtins["botmoveto"] = ::do_botmoveto; + level.bot_builtins["botmeleeparams"] = ::do_botmeleeparams; level.bot_builtins["isbot"] = ::do_isbot; level.bot_builtins["fs_fopen"] = ::do_fs_fopen; level.bot_builtins["fs_fclose"] = ::do_fs_fclose; @@ -20,40 +19,6 @@ do_printconsole( s ) println( s ); } -do_filewrite( file, contents, mode ) -{ - file = "scriptdata/" + file; - f = FS_FOpen( file, mode ); - - // always adds newline, strip from contents - if ( contents[contents.size - 1] == "\n" ) - { - contents = getsubstr( contents, 0, contents.size - 1 ); - } - - FS_WriteLine( f, contents ); - - FS_FClose( f ); -} - -do_fileread( file ) -{ - file = "scriptdata/" + file; - answer = ""; - - f = FS_FOpen( file, "read" ); - line = FS_ReadLine( f ); - - while ( isDefined( line ) ) - { - answer += line + "\n"; - line = FS_ReadLine( f ); - } - - FS_FClose( f ); - return answer; -} - do_fileexists( file ) { file = "scriptdata/" + file; @@ -79,6 +44,11 @@ do_botmoveto( where ) self BotMoveTo( where ); } +do_botmeleeparams( yaw, dist ) +{ + // cod4x removed lunging due to movement exploits +} + do_isbot() { return self.isbot;