From 271ea76c3e9eaced48318d85ee0590fddd8b16a0 Mon Sep 17 00:00:00 2001 From: ineed bots Date: Mon, 18 Dec 2023 23:42:48 -0600 Subject: [PATCH] casing fixes --- maps/bots/_bot.gsc | 208 +- maps/bots/_bot_debug.gsc | 62 +- maps/bots/_bot_internal.gsc | 4372 +++++++++++------------ maps/bots/_bot_script.gsc | 996 +++--- maps/bots/_bot_utility.gsc | 203 +- maps/bots/objectives/_manager.gsc | 36 +- maps/bots/objectives/_perkmachine.gsc | 40 +- maps/bots/objectives/_powerup.gsc | 22 +- maps/bots/objectives/_revive.gsc | 28 +- maps/bots/objectives/_treasurechest.gsc | 58 +- maps/bots/objectives/_utility.gsc | 42 +- maps/bots/objectives/_wallweapon.gsc | 44 +- scripts/sp/bots_adapter_pt4.gsc | 28 +- 13 files changed, 3064 insertions(+), 3075 deletions(-) diff --git a/maps/bots/_bot.gsc b/maps/bots/_bot.gsc index afc4c94..507ec17 100644 --- a/maps/bots/_bot.gsc +++ b/maps/bots/_bot.gsc @@ -7,100 +7,100 @@ */ init() { - level.bw_VERSION = "z0.1"; + level.bw_version = "z0.1"; - if ( getDvar( "bots_main" ) == "" ) - setDvar( "bots_main", true ); + if ( getdvar( "bots_main" ) == "" ) + setdvar( "bots_main", true ); - if ( !getDvarInt( "bots_main" ) ) + if ( !getdvarint( "bots_main" ) ) return; if ( !wait_for_builtins() ) - PrintLn( "FATAL: NO BUILT-INS FOR BOTS" ); + println( "FATAL: NO BUILT-INS FOR BOTS" ); thread load_waypoints(); thread hook_callbacks(); - if ( getDvar( "bots_main_GUIDs" ) == "" ) - setDvar( "bots_main_GUIDs", "" ); //guids of players who will be given host powers, comma seperated + if ( getdvar( "bots_main_GUIDs" ) == "" ) + setdvar( "bots_main_GUIDs", "" ); //guids of players who will be given host powers, comma seperated - if ( getDvar( "bots_main_firstIsHost" ) == "" ) - setDvar( "bots_main_firstIsHost", false ); //first player to connect is a host + if ( getdvar( "bots_main_firstIsHost" ) == "" ) + setdvar( "bots_main_firstIsHost", false ); //first player to connect is a host - if ( getDvar( "bots_main_waitForHostTime" ) == "" ) - setDvar( "bots_main_waitForHostTime", 10.0 ); //how long to wait to wait for the host player + if ( getdvar( "bots_main_waitForHostTime" ) == "" ) + setdvar( "bots_main_waitForHostTime", 10.0 ); //how long to wait to wait for the host player - if ( getDvar( "bots_main_kickBotsAtEnd" ) == "" ) - setDvar( "bots_main_kickBotsAtEnd", false ); //kicks the bots at game end + if ( getdvar( "bots_main_kickBotsAtEnd" ) == "" ) + setdvar( "bots_main_kickBotsAtEnd", false ); //kicks the bots at game end - if ( getDvar( "bots_manage_add" ) == "" ) - setDvar( "bots_manage_add", 0 ); //amount of bots to add to the game + if ( getdvar( "bots_manage_add" ) == "" ) + setdvar( "bots_manage_add", 0 ); //amount of bots to add to the game - if ( getDvar( "bots_manage_fill" ) == "" ) - setDvar( "bots_manage_fill", 0 ); //amount of bots to maintain + if ( getdvar( "bots_manage_fill" ) == "" ) + setdvar( "bots_manage_fill", 0 ); //amount of bots to maintain - if ( getDvar( "bots_manage_fill_mode" ) == "" ) - setDvar( "bots_manage_fill_mode", 0 ); //fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1 + if ( getdvar( "bots_manage_fill_mode" ) == "" ) + setdvar( "bots_manage_fill_mode", 0 ); //fill mode, 0 adds everyone, 1 just bots, 2 maintains at maps, 3 is 2 with 1 - if ( getDvar( "bots_manage_fill_kick" ) == "" ) - setDvar( "bots_manage_fill_kick", false ); //kick bots if too many + if ( getdvar( "bots_manage_fill_kick" ) == "" ) + setdvar( "bots_manage_fill_kick", false ); //kick bots if too many - if ( getDvar( "bots_skill" ) == "" ) - setDvar( "bots_skill", 0 ); //0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random + if ( getdvar( "bots_skill" ) == "" ) + setdvar( "bots_skill", 0 ); //0 is random, 1 is easy 7 is hard, 8 is custom, 9 is completely random - if ( getDvar( "bots_skill_hard" ) == "" ) - setDvar( "bots_skill_hard", 0 ); //amount of hard bots on axis team + if ( getdvar( "bots_skill_hard" ) == "" ) + setdvar( "bots_skill_hard", 0 ); //amount of hard bots on axis team - if ( getDvar( "bots_skill_med" ) == "" ) - setDvar( "bots_skill_med", 0 ); + if ( getdvar( "bots_skill_med" ) == "" ) + setdvar( "bots_skill_med", 0 ); - if ( getDvar( "bots_loadout_rank" ) == "" ) // what rank the bots should be around, -1 is around the players, 0 is all random - setDvar( "bots_loadout_rank", -1 ); + if ( getdvar( "bots_loadout_rank" ) == "" ) // what rank the bots should be around, -1 is around the players, 0 is all random + setdvar( "bots_loadout_rank", -1 ); - if ( getDvar( "bots_loadout_prestige" ) == "" ) // what pretige the bots will be, -1 is the players, -2 is random - setDvar( "bots_loadout_prestige", -1 ); + if ( getdvar( "bots_loadout_prestige" ) == "" ) // what pretige the bots will be, -1 is the players, -2 is random + setdvar( "bots_loadout_prestige", -1 ); - if ( getDvar( "bots_play_move" ) == "" ) //bots move - setDvar( "bots_play_move", true ); + if ( getdvar( "bots_play_move" ) == "" ) //bots move + setdvar( "bots_play_move", true ); - if ( getDvar( "bots_play_knife" ) == "" ) //bots knife - setDvar( "bots_play_knife", true ); + if ( getdvar( "bots_play_knife" ) == "" ) //bots knife + setdvar( "bots_play_knife", true ); - if ( getDvar( "bots_play_fire" ) == "" ) //bots fire - setDvar( "bots_play_fire", true ); + if ( getdvar( "bots_play_fire" ) == "" ) //bots fire + setdvar( "bots_play_fire", true ); - if ( getDvar( "bots_play_nade" ) == "" ) //bots grenade - setDvar( "bots_play_nade", true ); + if ( getdvar( "bots_play_nade" ) == "" ) //bots grenade + setdvar( "bots_play_nade", true ); - if ( getDvar( "bots_play_ads" ) == "" ) //bot ads - setDvar( "bots_play_ads", true ); + if ( getdvar( "bots_play_ads" ) == "" ) //bot ads + setdvar( "bots_play_ads", true ); - if ( getDvar( "bots_play_aim" ) == "" ) - setDvar( "bots_play_aim", true ); + if ( getdvar( "bots_play_aim" ) == "" ) + setdvar( "bots_play_aim", true ); - if ( getDvar( "bots_t8_mode" ) == "" ) - setDvar( "bots_t8_mode", false ); + if ( getdvar( "bots_t8_mode" ) == "" ) + setdvar( "bots_t8_mode", false ); - if ( getDvar( "bots_play_opendoors" ) == "" ) - setDvar( "bots_play_opendoors", true ); + if ( getdvar( "bots_play_opendoors" ) == "" ) + setdvar( "bots_play_opendoors", true ); - if ( !isDefined( game["botWarfare"] ) ) + if ( !isdefined( game["botWarfare"] ) ) game["botWarfare"] = true; - level.bots_minSprintDistance = 315; - level.bots_minSprintDistance *= level.bots_minSprintDistance; - level.bots_minGrenadeDistance = 256; - level.bots_minGrenadeDistance *= level.bots_minGrenadeDistance; - level.bots_maxGrenadeDistance = 1024; - level.bots_maxGrenadeDistance *= level.bots_maxGrenadeDistance; - level.bots_maxKnifeDistance = 128; - level.bots_maxKnifeDistance *= level.bots_maxKnifeDistance; - level.bots_goalDistance = 27.5; - level.bots_goalDistance *= level.bots_goalDistance; - level.bots_noADSDistance = 200; - level.bots_noADSDistance *= level.bots_noADSDistance; - level.bots_maxShotgunDistance = 500; - level.bots_maxShotgunDistance *= level.bots_maxShotgunDistance; + level.bots_minsprintdistance = 315; + level.bots_minsprintdistance *= level.bots_minsprintdistance; + level.bots_mingrenadedistance = 256; + level.bots_mingrenadedistance *= level.bots_mingrenadedistance; + level.bots_maxgrenadedistance = 1024; + level.bots_maxgrenadedistance *= level.bots_maxgrenadedistance; + level.bots_maxknifedistance = 128; + level.bots_maxknifedistance *= level.bots_maxknifedistance; + level.bots_goaldistance = 27.5; + level.bots_goaldistance *= level.bots_goaldistance; + level.bots_noadsdistance = 200; + level.bots_noadsdistance *= level.bots_noadsdistance; + level.bots_maxshotgundistance = 500; + level.bots_maxshotgundistance *= level.bots_maxshotgundistance; level.players = []; level.bots = []; @@ -132,19 +132,19 @@ handleBots() level thread diffBots(); level addBots(); - while ( !isDefined( level.intermission ) || !level.intermission ) + while ( !isdefined( level.intermission ) || !level.intermission ) wait 0.05; - setDvar( "bots_manage_add", getBotArray().size ); + setdvar( "bots_manage_add", getBotArray().size ); - if ( !getDvarInt( "bots_main_kickBotsAtEnd" ) ) + if ( !getdvarint( "bots_main_kickBotsAtEnd" ) ) return; bots = getBotArray(); for ( i = 0; i < bots.size; i++ ) { - BotBuiltinCmdExec( "clientkick " + bots[i] getEntityNumber() ); + BotBuiltinCmdExec( "clientkick " + bots[i] getentitynumber() ); } } @@ -153,9 +153,9 @@ handleBots() */ onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ) { - if ( self is_bot() && getDvarInt( "bots_t8_mode" ) ) + if ( self is_bot() && getdvarint( "bots_t8_mode" ) ) { - if ( ( level.script == "nazi_zombie_asylum" || level.script == "nazi_zombie_sumpf" ) && self hasPerk( "specialty_armorvest" ) ) + if ( ( level.script == "nazi_zombie_asylum" || level.script == "nazi_zombie_sumpf" ) && self hasperk( "specialty_armorvest" ) ) { iDamage = int( iDamage * 0.333 ); } @@ -171,17 +171,17 @@ onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, self maps\bots\_bot_script::onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ); } - self [[level.prevCallbackPlayerDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ); + self [[level.prevcallbackplayerdamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ); } onActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ) { - if ( isDefined( eAttacker ) && isPlayer( eAttacker ) && eAttacker is_bot() && getDvarInt( "bots_t8_mode" ) && ( !isDefined( self.magic_bullet_shield ) || !self.magic_bullet_shield ) ) + if ( isdefined( eAttacker ) && isplayer( eAttacker ) && eAttacker is_bot() && getdvarint( "bots_t8_mode" ) && ( !isdefined( self.magic_bullet_shield ) || !self.magic_bullet_shield ) ) { - iDamage += int( self.maxhealth * randomFloatRange( 0.25, 1.25 ) ); + iDamage += int( self.maxhealth * randomfloatrange( 0.25, 1.25 ) ); } - self [[level.prevCallbackActorDamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ); + self [[level.prevcallbackactordamage]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, iModelIndex, iTimeOffset ); } /* @@ -190,11 +190,11 @@ onActorDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, hook_callbacks() { wait 0.05; - level.prevCallbackPlayerDamage = level.callbackPlayerDamage; - level.callbackPlayerDamage = ::onPlayerDamage; + level.prevcallbackplayerdamage = level.callbackplayerdamage; + level.callbackplayerdamage = ::onPlayerDamage; - level.prevCallbackActorDamage = level.callbackActorDamage; - level.callbackActorDamage = ::onActorDamage; + level.prevcallbackactordamage = level.callbackactordamage; + level.callbackactordamage = ::onActorDamage; } /* @@ -231,9 +231,9 @@ onSpawnedAll() { self waittill( "spawned_player" ); - self.lastSpawnTime = getTime(); + self.lastspawntime = gettime(); - if ( getDvarInt( "bots_main_debug" ) ) + if ( getdvarint( "bots_main_debug" ) ) { self.score = 100000; } @@ -257,7 +257,7 @@ connected() { self endon( "disconnect" ); - if ( !isDefined( self.pers["bot_host"] ) ) + if ( !isdefined( self.pers["bot_host"] ) ) self thread doHostCheck(); level.players[level.players.size] = self; @@ -268,13 +268,13 @@ connected() if ( !self is_bot() ) return; - if ( !isDefined( self.pers["isBot"] ) ) + if ( !isdefined( self.pers["isBot"] ) ) { // fast restart... self.pers["isBot"] = true; } - if ( !isDefined( self.pers["isBotWarfare"] ) ) + if ( !isdefined( self.pers["isBotWarfare"] ) ) { self.pers["isBotWarfare"] = true; self thread added(); @@ -302,34 +302,34 @@ watchBotDebugEvent() { self waittill( "bot_event", msg, str, b, c, d, e, f, g ); - if ( GetDvarInt( "bots_main_debug" ) >= 2 ) + if ( getdvarint( "bots_main_debug" ) >= 2 ) { big_str = "Bot Warfare debug: " + self.playername + ": " + msg; - if ( isDefined( str ) && isString( str ) ) + if ( isdefined( str ) && isstring( str ) ) big_str += ", " + str; - if ( isDefined( b ) && isString( b ) ) + if ( isdefined( b ) && isstring( b ) ) big_str += ", " + b; - if ( isDefined( c ) && isString( c ) ) + if ( isdefined( c ) && isstring( c ) ) big_str += ", " + c; - if ( isDefined( d ) && isString( d ) ) + if ( isdefined( d ) && isstring( d ) ) big_str += ", " + d; - if ( isDefined( e ) && isString( e ) ) + if ( isdefined( e ) && isstring( e ) ) big_str += ", " + e; - if ( isDefined( f ) && isString( f ) ) + if ( isdefined( f ) && isstring( f ) ) big_str += ", " + f; - if ( isDefined( g ) && isString( g ) ) + if ( isdefined( g ) && isstring( g ) ) big_str += ", " + g; BotBuiltinPrintConsole( big_str ); } - else if ( msg == "debug" && GetDvarInt( "bots_main_debug" ) ) + else if ( msg == "debug" && getdvarint( "bots_main_debug" ) ) { BotBuiltinPrintConsole( "Bot Warfare debug: " + self.playername + ": " + str ); } @@ -367,9 +367,9 @@ add_bot() */ diffBots_loop() { - var_hard = getDVarInt( "bots_skill_hard" ); - var_med = getDVarInt( "bots_skill_med" ); - var_skill = getDvarInt( "bots_skill" ); + var_hard = getdvarint( "bots_skill_hard" ); + var_med = getdvarint( "bots_skill_med" ); + var_skill = getdvarint( "bots_skill" ); hard = 0; med = 0; @@ -382,7 +382,7 @@ diffBots_loop() { player = level.players[i]; - if ( !isDefined( player.pers["team"] ) ) + if ( !isdefined( player.pers["team"] ) ) continue; if ( !player is_bot() ) @@ -436,11 +436,11 @@ diffBots() */ addBots_loop() { - botsToAdd = GetDvarInt( "bots_manage_add" ); + botsToAdd = getdvarint( "bots_manage_add" ); if ( botsToAdd > 0 ) { - SetDvar( "bots_manage_add", 0 ); + setdvar( "bots_manage_add", 0 ); if ( botsToAdd > 4 ) botsToAdd = 4; @@ -452,12 +452,12 @@ addBots_loop() } } - fillMode = getDVarInt( "bots_manage_fill_mode" ); + fillMode = getdvarint( "bots_manage_fill_mode" ); if ( fillMode == 2 || fillMode == 3 ) - setDvar( "bots_manage_fill", getGoodMapAmount() ); + setdvar( "bots_manage_fill", getGoodMapAmount() ); - fillAmount = getDvarInt( "bots_manage_fill" ); + fillAmount = getdvarint( "bots_manage_fill" ); players = 0; bots = 0; @@ -480,13 +480,13 @@ addBots_loop() amount += players; if ( amount < fillAmount ) - setDvar( "bots_manage_add", 1 ); - else if ( amount > fillAmount && getDvarInt( "bots_manage_fill_kick" ) ) + setdvar( "bots_manage_add", 1 ); + else if ( amount > fillAmount && getdvarint( "bots_manage_fill_kick" ) ) { tempBot = getBotToKick(); - if ( isDefined( tempBot ) ) - BotBuiltinCmdExec( "clientkick " + tempBot getEntityNumber() ); + if ( isdefined( tempBot ) ) + BotBuiltinCmdExec( "clientkick " + tempBot getentitynumber() ); } } @@ -499,7 +499,7 @@ addBots() bot_wait_for_host(); - while ( !isDefined( level.intermission ) || !level.intermission ) + while ( !isdefined( level.intermission ) || !level.intermission ) { wait 1.5; diff --git a/maps/bots/_bot_debug.gsc b/maps/bots/_bot_debug.gsc index 29a0081..8c9ddc7 100644 --- a/maps/bots/_bot_debug.gsc +++ b/maps/bots/_bot_debug.gsc @@ -12,41 +12,41 @@ init() { - if ( getDvar( "bots_main_debug" ) == "" ) - setDvar( "bots_main_debug", 0 ); + if ( getdvar( "bots_main_debug" ) == "" ) + setdvar( "bots_main_debug", 0 ); - if ( !getDVarint( "bots_main_debug" ) || !getDVarint( "bots_main_debug_wp_vis" ) ) + if ( !getdvarint( "bots_main_debug" ) || !getdvarint( "bots_main_debug_wp_vis" ) ) return; - if ( !getDVarint( "developer" ) ) + if ( !getdvarint( "developer" ) ) { setdvar( "developer_script", 1 ); setdvar( "developer", 2 ); - setdvar( "sv_mapRotation", "map " + getDvar( "mapname" ) ); - exitLevel( false ); + setdvar( "sv_mapRotation", "map " + getdvar( "mapname" ) ); + exitlevel( false ); return; } - setDvar( "bots_main", false ); + setdvar( "bots_main", false ); setdvar( "bots_main_menu", false ); setdvar( "bots_manage_fill_mode", 0 ); setdvar( "bots_manage_fill", 0 ); setdvar( "bots_manage_add", 0 ); setdvar( "bots_manage_fill_kick", true ); - setDvar( "bots_manage_fill_spec", true ); + setdvar( "bots_manage_fill_spec", true ); - if ( getDvar( "bots_main_debug_distance" ) == "" ) - setDvar( "bots_main_debug_distance", 512.0 ); + if ( getdvar( "bots_main_debug_distance" ) == "" ) + setdvar( "bots_main_debug_distance", 512.0 ); - if ( getDvar( "bots_main_debug_cone" ) == "" ) - setDvar( "bots_main_debug_cone", 0.65 ); + if ( getdvar( "bots_main_debug_cone" ) == "" ) + setdvar( "bots_main_debug_cone", 0.65 ); - if ( getDvar( "bots_main_debug_minDist" ) == "" ) - setDvar( "bots_main_debug_minDist", 32.0 ); + if ( getdvar( "bots_main_debug_minDist" ) == "" ) + setdvar( "bots_main_debug_minDist", 32.0 ); - if ( getDvar( "bots_main_debug_drawThrough" ) == "" ) - setDvar( "bots_main_debug_drawThrough", false ); + if ( getdvar( "bots_main_debug_drawThrough" ) == "" ) + setdvar( "bots_main_debug_drawThrough", false ); thread load_waypoints(); @@ -149,7 +149,7 @@ toggle_link( firstwp, secondwp ) return; } - if ( isDefined( level.bot_ignore_links[key] ) && array_contains( level.bot_ignore_links[key], secnum ) ) + if ( isdefined( level.bot_ignore_links[key] ) && array_contains( level.bot_ignore_links[key], secnum ) ) { a = level.bot_ignore_links[key]; @@ -169,7 +169,7 @@ toggle_link( firstwp, secondwp ) } else { - if ( !isDefined( level.bot_ignore_links[key] ) ) + if ( !isdefined( level.bot_ignore_links[key] ) ) { level.bot_ignore_links[key] = []; } @@ -196,24 +196,24 @@ debug() wait 0.05; closest = -1; - myEye = self getTagOrigin( "j_head" ); - myAngles = self GetPlayerAngles(); + myEye = self gettagorigin( "j_head" ); + myAngles = self getplayerangles(); - for ( i = 0; i < level.waypointCount; i++ ) + for ( i = 0; i < level.waypointcount; i++ ) { if ( closest == -1 || closer( self.origin, level.waypoints[i].origin, level.waypoints[closest].origin ) ) closest = i; wpOrg = level.waypoints[i].origin + ( 0, 0, 25 ); - if ( distance( level.waypoints[i].origin, self.origin ) < getDvarFloat( "bots_main_debug_distance" ) && ( sightTracePassed( myEye, wpOrg, false, self ) || getDVarint( "bots_main_debug_drawThrough" ) ) && getConeDot( wpOrg, myEye, myAngles ) > getDvarFloat( "bots_main_debug_cone" ) ) + if ( distance( level.waypoints[i].origin, self.origin ) < getdvarfloat( "bots_main_debug_distance" ) && ( sighttracepassed( myEye, wpOrg, false, self ) || getdvarint( "bots_main_debug_drawThrough" ) ) && getConeDot( wpOrg, myEye, myAngles ) > getdvarfloat( "bots_main_debug_cone" ) ) { linked = level.waypoints[i] BotBuiltinGetLinkedNodes(); node_num_str = level.waypoints[i] BotBuiltinGetNodeNumber() + ""; for ( h = linked.size - 1; h >= 0; h-- ) { - if ( isDefined( level.bot_ignore_links[node_num_str] ) ) + if ( isdefined( level.bot_ignore_links[node_num_str] ) ) { found = false; this_node_num = linked[h] BotBuiltinGetNodeNumber(); @@ -236,9 +236,9 @@ debug() print3d( wpOrg, node_num_str, ( 1, 0, 0 ), 2 ); - if ( isDefined( level.waypoints[i].animscript ) ) + if ( isdefined( level.waypoints[i].animscript ) ) { - line( wpOrg, wpOrg + AnglesToForward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ) ); + line( wpOrg, wpOrg + anglestoforward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ) ); print3d( wpOrg + ( 0, 0, 15 ), level.waypoints[i].animscript, ( 1, 0, 0 ), 2 ); } } @@ -264,18 +264,18 @@ textScroll( string ) self endon( "disconnect" ); //thanks ActionScript - back = createBar( ( 0, 0, 0 ), 1000, 30 ); - back setPoint( "CENTER", undefined, 0, 220 ); + back = createbar( ( 0, 0, 0 ), 1000, 30 ); + back setpoint( "CENTER", undefined, 0, 220 ); self thread destroyOnDeath( back ); - text = createFontString( "default", 1.5 ); - text setText( string ); + text = createfontstring( "default", 1.5 ); + text settext( string ); self thread destroyOnDeath( text ); for ( ;; ) { - text setPoint( "CENTER", undefined, 1200, 220 ); - text setPoint( "CENTER", undefined, -1200, 220, 20 ); + text setpoint( "CENTER", undefined, 1200, 220 ); + text setpoint( "CENTER", undefined, -1200, 220, 20 ); wait 20; } } diff --git a/maps/bots/_bot_internal.gsc b/maps/bots/_bot_internal.gsc index 1a1c2e1..700dcdf 100644 --- a/maps/bots/_bot_internal.gsc +++ b/maps/bots/_bot_internal.gsc @@ -1,2186 +1,2186 @@ -#include common_scripts\utility; -#include maps\_utility; -#include maps\bots\_bot_utility; - -/* - When a bot is added (once ever) to the game (before connected). - We init all the persistent variables here. -*/ -added() -{ - self endon( "disconnect" ); - - self.pers["bots"] = []; - - self.pers["bots"]["skill"] = []; - self.pers["bots"]["skill"]["base"] = 7; // a base knownledge of the bot - self.pers["bots"]["skill"]["aim_time"] = 0.05; // how long it takes for a bot to aim to a location - self.pers["bots"]["skill"]["init_react_time"] = 0; // the reaction time of the bot for inital targets - self.pers["bots"]["skill"]["reaction_time"] = 0; // reaction time for the bots of reoccuring targets - self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; // how long a bot ads's when they cant see the target - self.pers["bots"]["skill"]["no_trace_look_time"] = 10000; // how long a bot will look at a target's last position - self.pers["bots"]["skill"]["remember_time"] = 25000; // how long a bot will remember a target before forgetting about it when they cant see the target - self.pers["bots"]["skill"]["fov"] = -1; // the fov of the bot, -1 being 360, 1 being 0 - self.pers["bots"]["skill"]["dist_max"] = 100000 * 2; // the longest distance a bot will target - self.pers["bots"]["skill"]["dist_start"] = 100000; // the start distance before bot's target abilitys diminish - self.pers["bots"]["skill"]["spawn_time"] = 0; // how long a bot waits after spawning before targeting, etc - self.pers["bots"]["skill"]["help_dist"] = 10000; // how far a bot has awareness - self.pers["bots"]["skill"]["semi_time"] = 0.05; // how fast a bot shoots semiauto - self.pers["bots"]["skill"]["shoot_after_time"] = 1; // how long a bot shoots after target dies/cant be seen - self.pers["bots"]["skill"]["aim_offset_time"] = 1; // how long a bot correct's their aim after targeting - self.pers["bots"]["skill"]["aim_offset_amount"] = 1; // how far a bot's incorrect aim is - self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; // how often a bot changes their bone target - self.pers["bots"]["skill"]["bones"] = "j_head"; // a list of comma seperated bones the bot will aim at - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; // a factor of how much ads to reduce when adsing - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; // a factor of how much more aimspeed delay to add - - self.pers["bots"]["behavior"] = []; - self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target - self.pers["bots"]["behavior"]["nade"] = 50; // percentage of how often the bot will grenade - self.pers["bots"]["behavior"]["sprint"] = 50; // percentage of how often the bot will sprint - self.pers["bots"]["behavior"]["camp"] = 50; // percentage of how often the bot will camp - self.pers["bots"]["behavior"]["follow"] = 50; // percentage of how often the bot will follow - self.pers["bots"]["behavior"]["crouch"] = 10; // percentage of how often the bot will crouch - self.pers["bots"]["behavior"]["switch"] = 1; // percentage of how often the bot will switch weapons - self.pers["bots"]["behavior"]["jump"] = 100; // percentage of how often the bot will jumpshot and dropshot - - self.pers["bots"]["behavior"]["quickscope"] = false; // is a quickscoper - self.pers["bots"]["behavior"]["initswitch"] = 10; // percentage of how often the bot will switch weapons on spawn -} - -/* - We clear all of the script variables and other stuff for the bots. -*/ -resetBotVars() -{ - self.bot.script_target = undefined; - self.bot.script_target_offset = undefined; - self.bot.target = undefined; - self.bot.targets = []; - self.bot.target_this_frame = undefined; - self.bot.after_target = undefined; - self.bot.after_target_pos = undefined; - self.bot.moveTo = self.origin; - - self.bot.script_aimpos = undefined; - - self.bot.script_goal = undefined; - self.bot.script_goal_dist = 0.0; - - self.bot.next_wp = -1; - self.bot.second_next_wp = -1; - self.bot.towards_goal = undefined; - self.bot.astar = []; - self.bot.stop_move = false; - self.bot.climbing = false; - self.bot.wantsprint = false; - self.bot.last_next_wp = -1; - self.bot.last_second_next_wp = -1; - - self.bot.isfrozen = false; - self.bot.sprintendtime = -1; - self.bot.isreloading = false; - self.bot.issprinting = false; - self.bot.isfragging = false; - self.bot.issmoking = false; - self.bot.isfraggingafter = false; - 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; - self.bot.last_fire_time = -1; - - self.bot.is_cur_full_auto = false; - self.bot.cur_weap_dist_multi = 1; - self.bot.is_cur_sniper = false; - - self.bot.prio_objective = false; - - self.bot.rand = randomInt( 100 ); - - self BotBuiltinBotStop(); -} - -/* - The callback hook when the bot gets damaged. -*/ -onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ) -{ -} - -/* - When a bot connects to the game. - This is called when a bot is added and when multiround gamemode starts. -*/ -connected() -{ - self endon( "disconnect" ); - - self.bot = spawnStruct(); - self resetBotVars(); - - self thread onPlayerSpawned(); -} - -/* - When the bot spawns. -*/ -onPlayerSpawned() -{ - self endon( "disconnect" ); - - for ( ;; ) - { - self waittill( "spawned_player" ); - - self resetBotVars(); - self thread onWeaponChange(); - - self thread reload_watch(); - self thread sprint_watch(); - - self thread spawned(); - } -} - -/* - Is the weap a sniper -*/ -IsWeapSniper( weap ) -{ - if ( weap == "none" ) - return false; - - if ( false /*maps\mp\gametypes\_missions::getWeaponClass( weap ) != "weapon_sniper"*/ ) - return false; - - return true; -} - -/* - When the bot changes weapon. -*/ -onWeaponChange() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - first = true; - - for ( ;; ) - { - newWeapon = undefined; - - if ( first ) - { - first = false; - newWeapon = self getCurrentWeapon(); - } - else - self waittill( "weapon_change", newWeapon ); - - self.bot.is_cur_full_auto = WeaponIsFullAuto( newWeapon ); - self.bot.cur_weap_dist_multi = SetWeaponDistMulti( newWeapon ); - self.bot.is_cur_sniper = IsWeapSniper( newWeapon ); - } -} - -/* - Sets the factor of distance for a weapon -*/ -SetWeaponDistMulti( weap ) -{ - if ( weap == "none" ) - return 1; - - switch ( weaponClass( weap ) ) - { - case "rifle": - return 0.9; - - case "smg": - return 0.7; - - case "pistol": - return 0.5; - - default: - return 1; - } -} - -/* - Update's the bot if it is reloading. -*/ -reload_watch() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - self waittill( "reload_start" ); - - self reload_watch_loop(); - } -} - -/* - Update's the bot if it is reloading. -*/ -reload_watch_loop() -{ - self.bot.isreloading = true; - - while ( true ) - { - ret = self waittill_any_timeout( 7.5, "reload" ); - - if ( ret == "timeout" ) - break; - - weap = self GetCurrentWeapon(); - - if ( weap == "none" ) - break; - - if ( self GetWeaponAmmoClip( weap ) >= WeaponClipSize( weap ) ) - break; - } - - self.bot.isreloading = false; -} - -/* - Updates the bot if it is sprinting. -*/ -sprint_watch() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - self waittill( "sprint_begin" ); - self.bot.issprinting = true; - self waittill( "sprint_end" ); - self.bot.issprinting = false; - self.bot.sprintendtime = getTime(); - } -} - -/* - We wait for a time defined by the bot's difficulty and start all threads that control the bot. -*/ -spawned() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - wait self.pers["bots"]["skill"]["spawn_time"]; - - self thread doBotMovement(); - self thread walk(); - self thread target(); - self thread target_cleanup(); - self thread updateBones(); - self thread aim(); - self thread watchHoldBreath(); - self thread stance(); - self thread onNewEnemy(); - self thread check_reload(); - - self notify( "bot_spawned" ); -} - -/* - When the bot gets a new enemy. -*/ -onNewEnemy() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - self waittill( "new_enemy" ); - - if ( !isDefined( self.bot.target ) ) - continue; - - if ( !isDefined( self.bot.target.entity ) || !isAi( self.bot.target.entity ) ) - continue; - - if ( self.bot.target.didlook ) - continue; - - self thread watchToLook(); - } -} - -/* - Bots will jump or dropshot their enemy player. -*/ -watchToLook() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - self endon( "new_enemy" ); - - for ( ;; ) - { - while ( isDefined( self.bot.target ) && self.bot.target.didlook ) - wait 0.05; - - while ( isDefined( self.bot.target ) && self.bot.target.no_trace_time ) - wait 0.05; - - if ( !isDefined( self.bot.target ) ) - break; - - self.bot.target.didlook = true; - - if ( self.bot.isfrozen ) - continue; - - if ( self.bot.target.dist > level.bots_maxShotgunDistance * 2 ) - continue; - - if ( self.bot.target.dist <= level.bots_maxKnifeDistance ) - continue; - - if ( !self canFire( self getCurrentWEapon() ) ) - continue; - - if ( !self isInRange( self.bot.target.dist, self getCurrentWEapon() ) ) - continue; - - if ( self.bot.is_cur_sniper ) - continue; - - if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["jump"] ) - continue; - - if ( !getDvarInt( "bots_play_jumpdrop" ) ) - continue; - - if ( isDefined( self.bot.jump_time ) && getTime() - self.bot.jump_time <= 5000 ) - continue; - - if ( self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"] ) - { - if ( self getStance() != "stand" ) - continue; - - self.bot.jump_time = getTime(); - self jump(); - } - else - { - if ( getConeDot( self.bot.target.last_seen_pos, self.origin, self getPlayerAngles() ) < 0.8 || self.bot.target.dist <= level.bots_noADSDistance ) - continue; - - self.bot.jump_time = getTime(); - self prone(); - self notify( "kill_goal" ); - wait 2.5; - self crouch(); - } - } -} - -/* - Bots will update its needed stance according to the nodes on the level. Will also allow the bot to sprint when it can. -*/ -stance_loop() -{ - self.bot.climbing = false; - - if ( self.bot.isfrozen ) - return; - - toStance = "stand"; - - if ( self.bot.next_wp != -1 ) - toStance = level.waypoints[self.bot.next_wp].type; - - if ( !isDefined( toStance ) ) - toStance = "stand"; - - if ( toStance == "stand" && randomInt( 100 ) <= self.pers["bots"]["behavior"]["crouch"] ) - toStance = "crouch"; - - if ( toStance == "climb" ) - { - self.bot.climbing = true; - toStance = "stand"; - } - - if ( toStance != "stand" && toStance != "crouch" && toStance != "prone" ) - toStance = "crouch"; - - toStance = "stand"; //Hack to make the bots never crouch - - if ( toStance == "stand" ) - self stand(); - else if ( toStance == "crouch" ) - self crouch(); - else - self prone(); - - curweap = self getCurrentWeapon(); - time = getTime(); - chance = self.pers["bots"]["behavior"]["sprint"]; - - if ( time - self.lastSpawnTime < 5000 ) - chance *= 2; - - if ( isDefined( self.bot.script_goal ) && DistanceSquared( self.origin, self.bot.script_goal ) > 256 * 256 ) - chance *= 2; - - if ( toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter ) - return; - - if ( randomInt( 100 ) > chance ) - return; - - if ( isDefined( self.bot.target ) && self canFire( curweap ) && self isInRange( self.bot.target.dist, curweap ) ) - return; - - if ( self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000 ) - return; - - if ( !isDefined( self.bot.towards_goal ) || DistanceSquared( self.origin, physicsTrace( self getEye(), self getEye() + anglesToForward( self getPlayerAngles() ) * 1024, false, undefined ) ) < level.bots_minSprintDistance || getConeDot( self.bot.towards_goal, self.origin, self GetPlayerAngles() ) < 0.75 ) - return; - - self thread sprint(); - self thread setBotWantSprint(); -} - -/* - Stops the sprint fix when goal is completed -*/ -setBotWantSprint() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - self notify( "setBotWantSprint" ); - self endon( "setBotWantSprint" ); - - self.bot.wantsprint = true; - - self waittill_notify_or_timeout( "kill_goal", 10 ); - - self.bot.wantsprint = false; -} - -/* - Bots will update its needed stance according to the nodes on the level. Will also allow the bot to sprint when it can. -*/ -stance() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - self waittill_either( "finished_static_waypoints", "new_static_waypoint" ); - - self stance_loop(); - } -} - -/* - Bot will wait until firing. -*/ -check_reload() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - self waittill_notify_or_timeout( "weapon_fired", 5 ); - self thread reload_thread(); - } -} - -/* - Bot will reload after firing if needed. -*/ -reload_thread() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - self endon( "weapon_fired" ); - - wait 2.5; - - if ( isDefined( self.bot.target ) || self.bot.isreloading || self.bot.isfraggingafter || self.bot.issmokingafter || self.bot.isfrozen ) - return; - - cur = self getCurrentWEapon(); - - if ( cur == "" || cur == "none" ) - return; - - if ( IsWeaponClipOnly( cur ) || !self GetWeaponAmmoStock( cur ) ) - return; - - maxsize = WeaponClipSize( cur ); - cursize = self GetWeaponammoclip( cur ); - - if ( cursize / maxsize < 0.5 ) - self thread reload(); -} - -target_cleanup() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - while ( true ) - { - wait 10; - curTime = getTime(); - targetKeys = getArrayKeys( self.bot.targets ); - - for ( i = 0; i < targetKeys.size; i++ ) - { - obj = self.bot.targets[ targetKeys[ i ] ]; - - if ( ( curTime - obj.time ) > 30000 ) - { - self.bot.targets[ targetKeys[ i ] ] = undefined; - } - } - } -} - -/* - The hold breath thread. -*/ -watchHoldBreath() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - wait 1; - - if ( self.bot.isfrozen ) - continue; - - self holdbreath( self playerADS() > 0 ); - } -} - -/* - Bot moves towards the point -*/ -doBotMovement() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - data = spawnStruct(); - data.wasMantling = false; - - for ( data.i = 0; true; data.i += 0.05 ) - { - wait 0.05; - - waittillframeend; - self doBotMovement_loop( data ); - } -} - -/* - Bot moves towards the point -*/ -doBotMovement_loop( data ) -{ - move_To = self.bot.moveTo; - angles = self GetPlayerAngles(); - dir = ( 0, 0, 0 ); - - if ( DistanceSquared( self.origin, move_To ) >= 49 ) - { - cosa = cos( 0 - angles[1] ); - sina = sin( 0 - angles[1] ); - - // get the direction - dir = move_To - self.origin; - - // rotate our direction according to our angles - dir = ( dir[0] * cosa - dir[1] * sina, - dir[0] * sina + dir[1] * cosa, - 0 ); - - // make the length 127 - dir = VectorNormalize( dir ) * 127; - - // invert the second component as the engine requires this - dir = ( dir[0], 0 - dir[1], 0 ); - } - - startPos = self.origin + ( 0, 0, 50 ); - startPosForward = startPos + anglesToForward( ( 0, angles[1], 0 ) ) * 25; - bt = bulletTrace( startPos, startPosForward, false, self ); - - if ( bt["fraction"] >= 1 ) - { - // check if need to jump - bt = bulletTrace( startPosForward, startPosForward - ( 0, 0, 40 ), false, self ); - - if ( bt["fraction"] < 1 && bt["normal"][2] > 0.9 && data.i > 1.5 ) - { - data.i = 0; - self thread jump(); - } - } - // check if need to knife glass - else if ( bt["surfacetype"] == "glass" ) - { - if ( data.i > 1.5 ) - { - data.i = 0; - self thread knife(); - } - } - else - { - // check if need to crouch - if ( bulletTracePassed( startPos - ( 0, 0, 25 ), startPosForward - ( 0, 0, 25 ), false, self ) && !self.bot.climbing ) - self crouch(); - } - - // move! - 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] ) ); -} - -/* - Bots will look at the pos -*/ -bot_lookat( pos, time, vel, doAimPredict ) -{ - self notify( "bots_aim_overlap" ); - self endon( "bots_aim_overlap" ); - self endon( "disconnect" ); - self endon( "zombified" ); - self endon( "spawned_player" ); - level endon ( "intermission" ); - - if ( ( isDefined( level.intermission ) && level.intermission ) || self.bot.isfrozen || !getDvarInt( "bots_play_aim" ) ) - return; - - if ( !isDefined( pos ) ) - return; - - if ( !isDefined( doAimPredict ) ) - doAimPredict = false; - - if ( !isDefined( time ) ) - time = 0.05; - - if ( !isDefined( vel ) ) - vel = ( 0, 0, 0 ); - - steps = int( time * 20 ); - - if ( steps < 1 ) - steps = 1; - - myEye = self getEye(); // get our eye pos - - if ( doAimPredict ) - { - myEye += ( self getVelocity() * 0.05 ) * ( steps - 1 ); // account for our velocity - - pos += ( vel * 0.05 ) * ( steps - 1 ); // add the velocity vector - } - - myAngle = self getPlayerAngles(); - angles = VectorToAngles( ( pos - myEye ) - anglesToForward( myAngle ) ); - - X = AngleClamp180( angles[0] - myAngle[0] ); - X = X / steps; - - Y = AngleClamp180( angles[1] - myAngle[1] ); - Y = Y / steps; - - for ( i = 0; i < steps; i++ ) - { - myAngle = ( AngleClamp180( myAngle[0] + X ), AngleClamp180( myAngle[1] + Y ), 0 ); - self setPlayerAngles( myAngle ); - wait 0.05; - } -} - -/* - Returns true if the bot can fire their current weapon. -*/ -canFire( curweap ) -{ - if ( curweap == "none" ) - return false; - - return self GetWeaponammoclip( curweap ); -} - -/* - Returns true if the bot is in range of their target. -*/ -isInRange( dist, curweap ) -{ - if ( curweap == "none" ) - return false; - - weapclass = weaponClass( curweap ); - - if ( weapclass == "spread" && dist > level.bots_maxShotgunDistance ) - return false; - - if ( curweap == "m2_flamethrower_mp" && dist > level.bots_maxShotgunDistance ) - return false; - - return true; -} - -/* - Returns true if the bot can ads their current gun. -*/ -canAds( dist, curweap ) -{ - if ( curweap == "none" ) - return false; - - if ( !getDvarInt( "bots_play_ads" ) ) - return false; - - far = level.bots_noADSDistance; - - if ( self hasPerk( "specialty_bulletaccuracy" ) ) - far *= 1.4; - - if ( dist < far ) - return false; - - weapclass = ( weaponClass( curweap ) ); - - if ( weapclass == "spread" || weapclass == "grenade" ) - return false; - - return true; -} - -/* - The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets. -*/ -target_loop() -{ - myEye = self getEye(); - theTime = getTime(); - myAngles = self GetPlayerAngles(); - myFov = self.pers["bots"]["skill"]["fov"]; - bestTargets = []; - bestTime = 2147483647; - rememberTime = self.pers["bots"]["skill"]["remember_time"]; - initReactTime = self.pers["bots"]["skill"]["init_react_time"]; - hasTarget = isDefined( self.bot.target ); - adsAmount = self PlayerADS(); - adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"]; - - if ( hasTarget && !isDefined( self.bot.target.entity ) ) - { - self.bot.target = undefined; - hasTarget = false; - } - - // reduce fov if ads'ing - if ( adsAmount > 0 ) - { - myFov *= 1 - adsFovFact * adsAmount; - } - - enemies = GetAISpeciesArray( "axis", "all" ); - - enemycount = enemies.size; - - for ( i = -1; i < enemycount; i++ ) - { - obj = undefined; - - if ( i == -1 ) - { - if ( !isDefined( self.bot.script_target ) ) - continue; - - ent = self.bot.script_target; - key = ent getEntityNumber() + ""; - daDist = distanceSquared( self.origin, ent.origin ); - obj = self.bot.targets[key]; - isObjDef = isDefined( obj ); - entOrigin = ent.origin; - - if ( isDefined( self.bot.script_target_offset ) ) - entOrigin += self.bot.script_target_offset; - - if ( bulletTracePassed( myEye, entOrigin, false, ent ) ) - { - if ( !isObjDef ) - { - obj = self createTargetObj( ent, theTime ); - obj.offset = self.bot.script_target_offset; - - self.bot.targets[key] = obj; - } - - self targetObjUpdateTraced( obj, daDist, ent, theTime, true ); - } - else - { - if ( !isObjDef ) - continue; - - self targetObjUpdateNoTrace( obj ); - - if ( obj.no_trace_time > rememberTime ) - { - self.bot.targets[key] = undefined; - continue; - } - } - } - else - { - enemy = enemies[i]; - - key = enemy getEntityNumber() + ""; - obj = self.bot.targets[key]; - daDist = distanceSquared( self.origin, enemy.origin ); - isObjDef = isDefined( obj ); - - targetHead = undefined; - targetAnkleLeft = undefined; - targetAnkleRight = undefined; - - if ( enemy targetIsDog() ) - { - targetHead = enemy getTagOrigin( "j_head" ); - targetAnkleLeft = enemy getTagOrigin( "j_ankle_le" ); - targetAnkleRight = enemy getTagOrigin( "j_ankle_ri" ); - } - else if ( !enemy targetIsGibbed() ) - { - targetHead = enemy getTagOrigin( "j_head" ); - targetAnkleLeft = enemy getTagOrigin( "j_ankle_le" ); - targetAnkleRight = enemy getTagOrigin( "j_ankle_ri" ); - } - else - { - targetHead = enemy getTagOrigin( "j_spinelower" ); - targetAnkleLeft = enemy getTagOrigin( "j_spinelower" ); - targetAnkleRight = enemy getTagOrigin( "j_spinelower" ); - } - - traceHead = bulletTrace( myEye, targetHead, false, enemy ); - traceAnkleLeft = bulletTrace( myEye, targetAnkleLeft, false, enemy ); - traceAnkleRight = bulletTrace( myEye, targetAnkleRight, false, enemy ); - - canTargetEnemy = ( ( sightTracePassed( myEye, targetHead, false, enemy ) || - sightTracePassed( myEye, targetAnkleLeft, false, enemy ) || - sightTracePassed( myEye, targetAnkleRight, false, enemy ) ) - - && ( ( traceHead["fraction"] >= 1.0 || traceHead["surfacetype"] == "glass" ) || - ( traceAnkleLeft["fraction"] >= 1.0 || traceAnkleLeft["surfacetype"] == "glass" ) || - ( traceAnkleRight["fraction"] >= 1.0 || traceAnkleRight["surfacetype"] == "glass" ) ) - - && ( getConeDot( enemy.origin, self.origin, myAngles ) >= myFov || - ( isObjDef && obj.trace_time ) ) - - && ( !isDefined( enemy.magic_bullet_shield ) || !enemy.magic_bullet_shield ) ); - - if ( isDefined( self.bot.target_this_frame ) && self.bot.target_this_frame == enemy ) - { - self.bot.target_this_frame = undefined; - - canTargetEnemy = true; - } - - if ( canTargetEnemy ) - { - if ( !isObjDef ) - { - obj = self createTargetObj( enemy, theTime ); - - self.bot.targets[key] = obj; - } - - self targetObjUpdateTraced( obj, daDist, enemy, theTime, false ); - } - else - { - if ( !isObjDef ) - continue; - - self targetObjUpdateNoTrace( obj ); - - if ( obj.no_trace_time > rememberTime ) - { - self.bot.targets[key] = undefined; - continue; - } - } - } - - if ( !isdefined( obj ) ) - continue; - - if ( theTime - obj.time < initReactTime ) - continue; - - timeDiff = theTime - obj.trace_time_time; - - if ( timeDiff < bestTime ) - { - bestTargets = []; - bestTime = timeDiff; - } - - if ( timeDiff == bestTime ) - bestTargets[key] = obj; - } - - if ( hasTarget && isDefined( bestTargets[self.bot.target.entity getEntityNumber() + ""] ) ) - return; - - closest = 2147483647; - toBeTarget = undefined; - - bestKeys = getArrayKeys( bestTargets ); - - for ( i = bestKeys.size - 1; i >= 0; i-- ) - { - theDist = bestTargets[bestKeys[i]].dist; - - if ( theDist > closest ) - continue; - - closest = theDist; - toBeTarget = bestTargets[bestKeys[i]]; - } - - beforeTargetID = -1; - newTargetID = -1; - - if ( hasTarget && isDefined( self.bot.target.entity ) ) - beforeTargetID = self.bot.target.entity getEntityNumber(); - - if ( isDefined( toBeTarget ) && isDefined( toBeTarget.entity ) ) - newTargetID = toBeTarget.entity getEntityNumber(); - - if ( beforeTargetID != newTargetID ) - { - self.bot.target = toBeTarget; - self notify( "new_enemy" ); - } -} - -/* - The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets. -*/ -target() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - wait 0.05; - - self target_loop(); - } -} - -/* - Picks a valid bone for enemy -*/ - -selectBoneForTarget( enemy, bones ) -{ - if ( enemy targetIsDog() ) - { - return "j_head"; - } - else if ( !enemy targetIsGibbed() ) - { - return PickRandom( bones ); - } - else - { - return "j_spineupper"; - } -} - -/* - Updates the bot's target bone -*/ -updateBones() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - bones = strtok( self.pers["bots"]["skill"]["bones"], "," ); - waittime = self.pers["bots"]["skill"]["bone_update_interval"]; - - for ( ;; ) - { - self waittill_notify_or_timeout( "new_enemy", waittime ); - - if ( !isDefined( self.bot.target ) || !isDefined( self.bot.target.entity ) ) - continue; - - self.bot.target.bone = selectBoneForTarget( self.bot.target.entity, bones ); - } -} - -/* - Creates the base target obj -*/ -createTargetObj( ent, theTime ) -{ - obj = spawnStruct(); - obj.entity = ent; - obj.last_seen_pos = ( 0, 0, 0 ); - obj.dist = 0; - obj.time = theTime; - obj.trace_time = 0; - obj.no_trace_time = 0; - obj.trace_time_time = 0; - obj.rand = randomInt( 100 ); - obj.didlook = false; - obj.offset = undefined; - obj.bone = undefined; - obj.aim_offset = undefined; - obj.aim_offset_base = undefined; - - return obj; -} - -/* - Updates the target object's difficulty missing aim, inaccurate shots -*/ -updateAimOffset( obj ) -{ - if ( !isDefined( obj.aim_offset_base ) ) - { - diffAimAmount = self.pers["bots"]["skill"]["aim_offset_amount"]; - - if ( diffAimAmount > 0 ) - obj.aim_offset_base = ( randomFloatRange( 0 - diffAimAmount, diffAimAmount ), - randomFloatRange( 0 - diffAimAmount, diffAimAmount ), - randomFloatRange( 0 - diffAimAmount, diffAimAmount ) ); - else - obj.aim_offset_base = ( 0, 0, 0 ); - } - - aimDiffTime = self.pers["bots"]["skill"]["aim_offset_time"] * 1000; - objCreatedFor = obj.trace_time; - - if ( objCreatedFor >= aimDiffTime ) - offsetScalar = 0; - else - offsetScalar = 1 - objCreatedFor / aimDiffTime; - - obj.aim_offset = obj.aim_offset_base * offsetScalar; -} - -/* - Updates the target object to be traced Has LOS -*/ -targetObjUpdateTraced( obj, daDist, ent, theTime, isScriptObj ) -{ - distClose = self.pers["bots"]["skill"]["dist_start"]; - distClose *= self.bot.cur_weap_dist_multi; - distClose *= distClose; - - distMax = self.pers["bots"]["skill"]["dist_max"]; - distMax *= self.bot.cur_weap_dist_multi; - distMax *= distMax; - - timeMulti = 1; - - if ( !isScriptObj ) - { - if ( daDist > distMax ) - timeMulti = 0; - else if ( daDist > distClose ) - timeMulti = 1 - ( ( daDist - distClose ) / ( distMax - distClose ) ); - } - - obj.no_trace_time = 0; - obj.trace_time += int( 50 * timeMulti ); - obj.dist = daDist; - obj.last_seen_pos = ent.origin; - obj.trace_time_time = theTime; - - self updateAimOffset( obj ); -} - -/* - Updates the target object to be not traced No LOS -*/ -targetObjUpdateNoTrace( obj ) -{ - obj.no_trace_time += 50; - obj.trace_time = 0; - obj.didlook = false; -} - -/* - Assigns the bot's after target (bot will keep firing at a target after no sight or death) -*/ -start_bot_after_target( who ) -{ - self endon( "disconnect" ); - self endon( "death" ); - - self.bot.after_target = who; - self.bot.after_target_pos = who.origin; - - self notify( "kill_after_target" ); - self endon( "kill_after_target" ); - - wait self.pers["bots"]["skill"]["shoot_after_time"]; - - self.bot.after_target = undefined; -} - -/* - Clears the bot's after target -*/ -clear_bot_after_target() -{ - self.bot.after_target = undefined; - self notify( "kill_after_target" ); -} - -/* - This is the bot's main aimming thread. The bot will aim at its targets or a node its going towards. Bots will aim, fire, ads, grenade. -*/ -aim_loop() -{ - aimspeed = self.pers["bots"]["skill"]["aim_time"]; - - eyePos = self getEye(); - curweap = self getCurrentWeapon(); - angles = self GetPlayerAngles(); - adsAmount = self PlayerADS(); - adsAimSpeedFact = self.pers["bots"]["skill"]["ads_aimspeed_multi"]; - - // reduce aimspeed if ads'ing - if ( adsAmount > 0 ) - { - aimspeed *= 1 + adsAimSpeedFact * adsAmount; - } - - if ( isDefined( self.bot.target ) && isDefined( self.bot.target.entity ) && !( self.bot.prio_objective && isDefined( self.bot.script_aimpos ) ) ) - { - no_trace_time = self.bot.target.no_trace_time; - no_trace_look_time = self.pers["bots"]["skill"]["no_trace_look_time"]; - - if ( no_trace_time <= no_trace_look_time ) - { - trace_time = self.bot.target.trace_time; - last_pos = self.bot.target.last_seen_pos; - target = self.bot.target.entity; - conedot = 0; - isact = isAi( self.bot.target.entity ); - - offset = self.bot.target.offset; - - if ( !isDefined( offset ) ) - offset = ( 0, 0, 0 ); - - aimoffset = self.bot.target.aim_offset; - - if ( !isDefined( aimoffset ) ) - aimoffset = ( 0, 0, 0 ); - - dist = self.bot.target.dist; - rand = self.bot.target.rand; - no_trace_ads_time = self.pers["bots"]["skill"]["no_trace_ads_time"]; - reaction_time = self.pers["bots"]["skill"]["reaction_time"]; - nadeAimOffset = 0; - - bone = self.bot.target.bone; - - if ( !isDefined( bone ) ) - bone = "j_spineupper"; - - if ( self.bot.isfraggingafter || self.bot.issmokingafter ) - nadeAimOffset = dist / 3000; - else if ( curweap != "none" && weaponClass( curweap ) == "grenade" ) - { - if ( true /*maps\mp\gametypes\_missions::getWeaponClass( curweap ) == "weapon_projectile"*/ ) - nadeAimOffset = dist / 16000; - else - nadeAimOffset = dist / 3000; - } - - if ( no_trace_time && ( !isDefined( self.bot.after_target ) || self.bot.after_target != target ) ) - { - if ( no_trace_time > no_trace_ads_time ) - { - if ( isact ) - { - //better room to nade? cook time function with dist? - if ( !self.bot.isfraggingafter && !self.bot.issmokingafter ) - { - nade = self getValidGrenade(); - - if ( isDefined( nade ) && rand <= self.pers["bots"]["behavior"]["nade"] && bulletTracePassed( eyePos, eyePos + ( 0, 0, 75 ), false, self ) && bulletTracePassed( last_pos, last_pos + ( 0, 0, 100 ), false, target ) && dist > level.bots_minGrenadeDistance && dist < level.bots_maxGrenadeDistance && getDvarInt( "bots_play_nade" ) ) - { - time = 0.5; - - if ( nade == "stielhandgranate" ) - time = 2; - - if ( !isSecondaryGrenade( nade ) ) - self thread frag( time ); - else - self thread smoke( time ); - - self notify( "kill_goal" ); - } - } - } - } - else - { - 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(); - } - } - - self thread bot_lookat( last_pos + ( 0, 0, self GetPlayerViewHeight() + nadeAimOffset ), aimspeed ); - return; - } - - if ( trace_time ) - { - if ( isact ) - { - aimpos = target getTagOrigin( bone ); - - if ( !isDefined( aimpos ) ) - return; - - aimpos += offset; - aimpos += aimoffset; - aimpos += ( 0, 0, nadeAimOffset ); - - conedot = getConeDot( aimpos, eyePos, angles ); - - 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 getAiVelocity(), true ); - } - else - { - aimpos = target.origin; - aimpos += offset; - aimpos += aimoffset; - aimpos += ( 0, 0, nadeAimOffset ); - - conedot = getConeDot( aimpos, eyePos, angles ); - - if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 ) - self thread bot_lookat( aimpos, 0.05 ); - else - self thread bot_lookat( aimpos, aimspeed ); - } - - if ( isact && !self.bot.isknifingafter && conedot > 0.9 && dist < level.bots_maxKnifeDistance && trace_time > reaction_time && !self.bot.isreloading && getDvarInt( "bots_play_knife" ) ) - { - self clear_bot_after_target(); - self thread knife( target ); - return; - } - - if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) - return; - - canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); - - if ( canADS ) - { - stopAdsOverride = false; - - if ( self.bot.is_cur_sniper ) - { - if ( self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000 ) - stopAdsOverride = true; - else - self notify( "kill_goal" ); - } - - if ( !stopAdsOverride ) - self thread pressAds(); - } - - if ( trace_time > reaction_time ) - { - if ( ( !canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone" ) && ( conedot > 0.99 || dist < level.bots_maxKnifeDistance ) && getDvarInt( "bots_play_fire" ) ) - self botFire(); - - if ( isact ) - self thread start_bot_after_target( target ); - } - - return; - } - } - } - - if ( isDefined( self.bot.after_target ) ) - { - nadeAimOffset = 0; - last_pos = self.bot.after_target_pos; - dist = DistanceSquared( self.origin, last_pos ); - - if ( self.bot.isfraggingafter || self.bot.issmokingafter ) - nadeAimOffset = dist / 3000; - else if ( curweap != "none" && weaponClass( curweap ) == "grenade" ) - { - if ( true /*maps\mp\gametypes\_missions::getWeaponClass( curweap ) == "weapon_projectile"*/ ) - nadeAimOffset = dist / 16000; - else - nadeAimOffset = dist / 3000; - } - - aimpos = last_pos + ( 0, 0, self GetPlayerViewHeight() + nadeAimOffset ); - conedot = getConeDot( aimpos, eyePos, angles ); - - self thread bot_lookat( aimpos, aimspeed ); - - if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) - return; - - canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); - - if ( canADS ) - { - stopAdsOverride = false; - - if ( self.bot.is_cur_sniper ) - { - if ( self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && getTime() - self.bot.last_fire_time < 1000 ) - stopAdsOverride = true; - else - self notify( "kill_goal" ); - } - - if ( !stopAdsOverride ) - self thread pressAds(); - } - - if ( ( !canADS || adsAmount >= 1.0 || self InLastStand() || self GetStance() == "prone" ) && ( conedot > 0.95 || dist < level.bots_maxKnifeDistance ) && getDvarInt( "bots_play_fire" ) ) - self botFire(); - - return; - } - - if ( self.bot.next_wp != -1 && isDefined( level.waypoints[self.bot.next_wp].angles ) && false ) - { - forwardPos = anglesToForward( level.waypoints[self.bot.next_wp].angles ) * 1024; - - self thread bot_lookat( eyePos + forwardPos, aimspeed ); - } - else if ( isDefined( self.bot.script_aimpos ) ) - { - self thread bot_lookat( self.bot.script_aimpos, aimspeed ); - } - else - { - lookat = undefined; - - if ( self.bot.second_next_wp != -1 && !self.bot.issprinting && !self.bot.climbing ) - lookat = level.waypoints[self.bot.second_next_wp].origin; - else if ( isDefined( self.bot.towards_goal ) ) - lookat = self.bot.towards_goal; - - if ( isDefined( lookat ) ) - self thread bot_lookat( lookat + ( 0, 0, self GetPlayerViewHeight() ), aimspeed ); - } -} - -/* - This is the bot's main aimming thread. The bot will aim at its targets or a node its going towards. Bots will aim, fire, ads, grenade. -*/ -aim() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - wait 0.05; - - if ( ( isDefined( level.intermission ) && level.intermission ) || self.bot.isfrozen ) - continue; - - self aim_loop(); - } -} - -/* - This is the main walking logic for the bot. -*/ -walk() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - wait 0.05; - - self botSetMoveTo( self.origin ); - - if ( !getDvarInt( "bots_play_move" ) ) - continue; - - if ( ( isdefined( level.intermission ) && level.intermission ) || self.bot.isfrozen || self.bot.stop_move ) - continue; - - self walk_loop(); - } -} - -/* - This is the main walking logic for the bot. -*/ -walk_loop() -{ - shouldTarget = isDefined( self.bot.target ) && isDefined( self.bot.target.entity ) && !self.bot.prio_objective; - - if ( shouldTarget ) - { - curweap = self getCurrentWeapon(); - - if ( self.bot.isfraggingafter || self.bot.issmokingafter ) - { - return; - } - - if ( isAi( self.bot.target.entity ) && self.bot.target.trace_time && self canFire( curweap ) && self isInRange( self.bot.target.dist, curweap ) ) - { - if ( self inLastStand() || self GetStance() == "prone" || ( self.bot.is_cur_sniper && self PlayerADS() > 0 ) ) - return; - - if ( self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"] ) - self strafe( self.bot.target.entity ); - - return; - } - } - - dist = 16; - - goal = self getRandomGoal(); - - isScriptGoal = false; - - if ( isDefined( self.bot.script_goal ) && !shouldTarget ) - { - goal = self.bot.script_goal; - dist = self.bot.script_goal_dist; - - isScriptGoal = true; - } - else - { - if ( shouldTarget ) - goal = self.bot.target.last_seen_pos; - - self notify( "new_goal_internal" ); - } - - self doWalk( goal, dist, isScriptGoal ); - self.bot.towards_goal = undefined; - self.bot.next_wp = -1; - self.bot.second_next_wp = -1; -} - -/* - Will walk to the given goal when dist near. Uses AStar path finding with the level's nodes. -*/ -doWalk( goal, dist, isScriptGoal ) -{ - level endon( "intermission" ); - self endon( "kill_goal" ); - self endon( "goal_internal" ); //so that the watchOnGoal notify can happen same frame, not a frame later - - dist *= dist; - - if ( isScriptGoal ) - self thread doWalkScriptNotify(); - - self thread killWalkOnEvents(); - self thread watchOnGoal( goal, dist ); - - current = self initAStar( goal ); - - path_was_truncated = ( current + 1 ) >= 32; - - if ( current <= -1 ) - { - self notify( "bad_path_internal" ); - return; - } - - // skip waypoints we already completed to prevent rubber banding - if ( current > 0 && self.bot.astar[current] == self.bot.last_next_wp && self.bot.astar[current - 1] == self.bot.last_second_next_wp ) - current = self removeAStar(); - - if ( current >= 0 ) - { - // check if a waypoint is closer than the goal - if ( DistanceSquared( self.origin, level.waypoints[self.bot.astar[current]].origin ) < DistanceSquared( self.origin, goal ) || DistanceSquared( level.waypoints[self.bot.astar[current]].origin, PlayerPhysicsTrace( self.origin + ( 0, 0, 32 ), level.waypoints[self.bot.astar[current]].origin ) ) > 1.0 ) - { - while ( current >= 0 ) - { - self.bot.next_wp = self.bot.astar[current]; - self.bot.second_next_wp = -1; - - if ( current > 0 ) - self.bot.second_next_wp = self.bot.astar[current - 1]; - - self notify( "new_static_waypoint" ); - - self movetowards( level.waypoints[self.bot.next_wp].origin ); - self.bot.last_next_wp = self.bot.next_wp; - self.bot.last_second_next_wp = self.bot.second_next_wp; - - current = self removeAStar(); - } - } - } - - if ( path_was_truncated ) - { - self notify( "kill_goal" ); - return; - } - - self.bot.next_wp = -1; - self.bot.second_next_wp = -1; - self notify( "finished_static_waypoints" ); - - if ( DistanceSquared( self.origin, goal ) > dist ) - { - self.bot.last_next_wp = -1; - self.bot.last_second_next_wp = -1; - self movetowards( goal ); // any better way?? - } - - self notify( "finished_goal" ); - - wait 1; - - if ( DistanceSquared( self.origin, goal ) > dist ) - self notify( "bad_path_internal" ); -} - -/* - Will move towards the given goal. Will try to not get stuck by crouching, then jumping and then strafing around objects. -*/ -movetowards( goal ) -{ - if ( !isDefined( goal ) ) - return; - - self.bot.towards_goal = goal; - - lastOri = self.origin; - stucks = 0; - timeslow = 0; - time = 0; - - if ( self.bot.issprinting ) - tempGoalDist = level.bots_goalDistance * 2; - else - tempGoalDist = level.bots_goalDistance; - - while ( distanceSquared( self.origin, goal ) > tempGoalDist ) - { - self botSetMoveTo( goal ); - - if ( time > 3000 ) - { - time = 0; - - if ( distanceSquared( self.origin, lastOri ) < 32 * 32 ) - { - self thread knife(); - wait 0.5; - - stucks++; - - randomDir = self getRandomLargestStafe( stucks ); - - self BotNotifyBotEvent( "stuck" ); - - self botSetMoveTo( randomDir ); - wait stucks; - self stand(); - - self.bot.last_next_wp = -1; - self.bot.last_second_next_wp = -1; - } - - lastOri = self.origin; - } - else if ( timeslow > 0 && ( timeslow % 1000 ) == 0 ) - { - self thread doMantle(); - } - else if ( time == 2000 ) - { - if ( distanceSquared( self.origin, lastOri ) < 32 * 32 ) - self crouch(); - } - else if ( time == 1750 ) - { - if ( distanceSquared( self.origin, lastOri ) < 32 * 32 ) - { - // check if directly above or below - if ( abs( goal[2] - self.origin[2] ) > 64 && getConeDot( goal + ( 1, 1, 0 ), self.origin + ( -1, -1, 0 ), VectorToAngles( ( goal[0], goal[1], self.origin[2] ) - self.origin ) ) < 0.64 && DistanceSquared2D( self.origin, goal ) < 32 * 32 ) - { - stucks = 2; - } - } - } - - wait 0.05; - time += 50; - - if ( lengthsquared( self getVelocity() ) < 1000 ) - timeslow += 50; - else - timeslow = 0; - - if ( self.bot.issprinting ) - tempGoalDist = level.bots_goalDistance * 2; - else - tempGoalDist = level.bots_goalDistance; - - if ( stucks >= 2 ) - self notify( "bad_path_internal" ); - } - - self.bot.towards_goal = undefined; - self notify( "completed_move_to" ); -} - -/* - The bot will strafe left or right from their enemy. -*/ -strafe( target ) -{ - self endon( "kill_goal" ); - self thread killWalkOnEvents(); - - angles = VectorToAngles( vectorNormalize( target.origin - self.origin ) ); - anglesLeft = ( 0, angles[1] + 90, 0 ); - anglesRight = ( 0, angles[1] - 90, 0 ); - - myOrg = self.origin + ( 0, 0, 16 ); - left = myOrg + anglestoforward( anglesLeft ) * 500; - right = myOrg + anglestoforward( anglesRight ) * 500; - - traceLeft = BulletTrace( myOrg, left, false, self ); - traceRight = BulletTrace( myOrg, right, false, self ); - - strafe = traceLeft["position"]; - - if ( traceRight["fraction"] > traceLeft["fraction"] ) - strafe = traceRight["position"]; - - self.bot.last_next_wp = -1; - self.bot.last_second_next_wp = -1; - self botSetMoveTo( strafe ); - wait 2; - self notify( "kill_goal" ); -} - -/* - Will return the pos of the largest trace from the bot. -*/ -getRandomLargestStafe( dist ) -{ - //find a better algo? - traces = NewHeap( ::HeapTraceFraction ); - myOrg = self.origin + ( 0, 0, 16 ); - - traces HeapInsert( bulletTrace( myOrg, myOrg + ( -100 * dist, 0, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( 100 * dist, 0, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( 0, 100 * dist, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( 0, -100 * dist, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( -100 * dist, -100 * dist, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( -100 * dist, 100 * dist, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( 100 * dist, -100 * dist, 0 ), false, self ) ); - traces HeapInsert( bulletTrace( myOrg, myOrg + ( 100 * dist, 100 * dist, 0 ), false, self ) ); - - toptraces = []; - - top = traces.data[0]; - toptraces[toptraces.size] = top; - traces HeapRemove(); - - while ( traces.data.size && top["fraction"] - traces.data[0]["fraction"] < 0.1 ) - { - toptraces[toptraces.size] = traces.data[0]; - traces HeapRemove(); - } - - return toptraces[randomInt( toptraces.size )]["position"]; -} - -/* - Calls the astar search algorithm for the path to the goal. -*/ -initAStar( goal ) -{ - nodes = BotBuiltinGeneratePath( self.origin, goal, self.team ); - - if ( !isDefined( nodes ) || nodes.size <= 0 ) - { - //Try again to find a path to the origin using best effort algo - nodes = BotBuiltinGeneratePath( self.origin, goal, self.team, 192.0 ); - - if ( !isDefined( nodes ) || nodes.size <= 0 ) - { - self.bot.astar = []; - return -1; - } - } - - node_indexes = []; - - for ( i = nodes.size - 1; i >= 0; i-- ) - { - node_indexes[ node_indexes.size ] = nodes[ i ] BotBuiltinGetNodeNumber(); - } - - self.bot.astar = node_indexes; - - return self.bot.astar.size - 1; -} - -/* - Cleans up the astar nodes for one node. -*/ -removeAStar() -{ - remove = self.bot.astar.size - 1; - - self.bot.astar[remove] = undefined; - - return self.bot.astar.size - 1; -} - -/* - Does the notify for goal completion for outside scripts -*/ -doWalkScriptNotify() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - self endon( "kill_goal" ); - - if ( self waittill_either_return( "goal_internal", "bad_path_internal" ) == "goal_internal" ) - self notify( "goal" ); - else - self notify( "bad_path" ); -} - -/* - Will stop the goal walk when an enemy is found or flashed or a new goal appeared for the bot. -*/ -killWalkOnEvents() -{ - self endon( "kill_goal" ); - self endon( "disconnect" ); - self endon( "zombified" ); - - self waittill_any( "new_enemy", "new_goal_internal", "goal_internal", "bad_path_internal" ); - - waittillframeend; - - self notify( "kill_goal" ); -} - -/* - Will kill the goal when the bot made it to its goal. -*/ -watchOnGoal( goal, dis ) -{ - self endon( "disconnect" ); - self endon( "zombified" ); - self endon( "kill_goal" ); - - while ( DistanceSquared( self.origin, goal ) > dis ) - wait 0.05; - - self notify( "goal_internal" ); -} - -/* - Bot will move towards here -*/ -botSetMoveTo( where ) -{ - self.bot.moveTo = where; -} - -/* - Bot will press ADS for a time. -*/ -pressADS( time ) -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_ads" ); - self endon( "bot_ads" ); - - if ( !isDefined( time ) ) - time = 0.05; - - self BotBuiltinBotAction( "+ads" ); - - if ( time ) - wait time; - - self BotBuiltinBotAction( "-ads" ); -} - -/* - Bot will hold the frag button for a time -*/ -frag( time ) -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_frag" ); - self endon( "bot_frag" ); - - if ( !isDefined( time ) ) - time = 0.05; - - self BotBuiltinBotAction( "+frag" ); - self.bot.isfragging = true; - self.bot.isfraggingafter = true; - - if ( time ) - wait time; - - self BotBuiltinBotAction( "-frag" ); - self.bot.isfragging = false; - - wait 1.25; - self.bot.isfraggingafter = false; -} - -/* - Bot will hold breath if true or not -*/ -holdbreath( what ) -{ - if ( what ) - self BotBuiltinBotAction( "+holdbreath" ); - else - self BotBuiltinBotAction( "-holdbreath" ); -} - -/* - Bot will hold the 'smoke' button for a time. -*/ -smoke( time ) -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_smoke" ); - self endon( "bot_smoke" ); - - if ( !isDefined( time ) ) - time = 0.05; - - self BotBuiltinBotAction( "+smoke" ); - self.bot.issmoking = true; - self.bot.issmokingafter = true; - - if ( time ) - wait time; - - self BotBuiltinBotAction( "-smoke" ); - self.bot.issmoking = false; - - wait 1.25; - self.bot.issmokingafter = false; -} - -/* - Waits a time defined by their difficulty for semi auto guns (no rapid fire) -*/ -doSemiTime() -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_semi_time" ); - self endon( "bot_semi_time" ); - - self.bot.semi_time = true; - wait self.pers["bots"]["skill"]["semi_time"]; - self.bot.semi_time = false; -} - -/* - Bots will fire their gun. -*/ -botFire() -{ - self.bot.last_fire_time = getTime(); - - if ( self.bot.is_cur_full_auto ) - { - self thread pressFire(); - return; - } - - if ( self.bot.semi_time ) - return; - - self thread pressFire(); - self thread doSemiTime(); -} - -/* - Bots do the mantle -*/ -doMantle() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - self endon( "kill_goal" ); - - self jump(); - - wait 0.35; - - self jump(); -} - -/* - Bot will fire for a time. -*/ -pressFire( time ) -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_fire" ); - self endon( "bot_fire" ); - - if ( !isDefined( time ) ) - time = 0.05; - - self BotBuiltinBotAction( "+fire" ); - - if ( time ) - wait time; - - self BotBuiltinBotAction( "-fire" ); -} - -/* - Bot will reload. -*/ -reload() -{ - self endon( "death" ); - self endon( "disconnect" ); - self notify( "bot_reload" ); - self endon( "bot_reload" ); - - self BotBuiltinBotAction( "+reload" ); - wait 0.05; - self BotBuiltinBotAction( "-reload" ); -} - -/* - Performs melee target -*/ -do_knife_target( target ) -{ - self endon( "death" ); - self endon( "disconnect" ); - self endon( "bot_knife" ); - - if ( !getDvarInt( "aim_automelee_enabled" ) || !self isOnGround() || self GetStance() == "prone" || self InLastStand() ) - { - self.bot.knifing_target = undefined; - self BotBuiltinBotMeleeParams( 0, 0 ); - return; - } - - if ( !isDefined( target ) || ( !isPlayer( target ) && !isai( 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( target ) -{ - self endon( "zombified" ); - 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; - - self BotBuiltinBotAction( "+melee" ); - wait 0.05; - self BotBuiltinBotAction( "-melee" ); - - self.bot.isknifing = false; - - wait 1; - - self.bot.isknifingafter = false; -} - -/* - Bot will press use for a time. -*/ -use( time ) -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_use" ); - self endon( "bot_use" ); - - if ( !isDefined( time ) ) - time = 0.05; - - self BotBuiltinBotAction( "+activate" ); - - if ( time ) - wait time; - - self BotBuiltinBotAction( "-activate" ); -} - -/* - Bot will jump. -*/ -jump() -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_jump" ); - self endon( "bot_jump" ); - - if ( self getStance() != "stand" ) - { - self stand(); - wait 1; - } - - self BotBuiltinBotAction( "+gostand" ); - wait 0.05; - self BotBuiltinBotAction( "-gostand" ); -} - -/* - Bot will stand. -*/ -stand() -{ - self BotBuiltinBotAction( "-gocrouch" ); - self BotBuiltinBotAction( "-goprone" ); -} - -/* - Bot will crouch. -*/ -crouch() -{ - self BotBuiltinBotAction( "+gocrouch" ); - self BotBuiltinBotAction( "-goprone" ); -} - -/* - Bot will prone. -*/ -prone() -{ - self BotBuiltinBotAction( "-gocrouch" ); - self BotBuiltinBotAction( "+goprone" ); -} - -/* - Bot will sprint. -*/ -sprint() -{ - self endon( "zombified" ); - self endon( "disconnect" ); - self notify( "bot_sprint" ); - self endon( "bot_sprint" ); - - self BotBuiltinBotAction( "+sprint" ); - wait 0.05; - self BotBuiltinBotAction( "-sprint" ); -} +#include common_scripts\utility; +#include maps\_utility; +#include maps\bots\_bot_utility; + +/* + When a bot is added (once ever) to the game (before connected). + We init all the persistent variables here. +*/ +added() +{ + self endon( "disconnect" ); + + self.pers["bots"] = []; + + self.pers["bots"]["skill"] = []; + self.pers["bots"]["skill"]["base"] = 7; // a base knownledge of the bot + self.pers["bots"]["skill"]["aim_time"] = 0.05; // how long it takes for a bot to aim to a location + self.pers["bots"]["skill"]["init_react_time"] = 0; // the reaction time of the bot for inital targets + self.pers["bots"]["skill"]["reaction_time"] = 0; // reaction time for the bots of reoccuring targets + self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; // how long a bot ads's when they cant see the target + self.pers["bots"]["skill"]["no_trace_look_time"] = 10000; // how long a bot will look at a target's last position + self.pers["bots"]["skill"]["remember_time"] = 25000; // how long a bot will remember a target before forgetting about it when they cant see the target + self.pers["bots"]["skill"]["fov"] = -1; // the fov of the bot, -1 being 360, 1 being 0 + self.pers["bots"]["skill"]["dist_max"] = 100000 * 2; // the longest distance a bot will target + self.pers["bots"]["skill"]["dist_start"] = 100000; // the start distance before bot's target abilitys diminish + self.pers["bots"]["skill"]["spawn_time"] = 0; // how long a bot waits after spawning before targeting, etc + self.pers["bots"]["skill"]["help_dist"] = 10000; // how far a bot has awareness + self.pers["bots"]["skill"]["semi_time"] = 0.05; // how fast a bot shoots semiauto + self.pers["bots"]["skill"]["shoot_after_time"] = 1; // how long a bot shoots after target dies/cant be seen + self.pers["bots"]["skill"]["aim_offset_time"] = 1; // how long a bot correct's their aim after targeting + self.pers["bots"]["skill"]["aim_offset_amount"] = 1; // how far a bot's incorrect aim is + self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; // how often a bot changes their bone target + self.pers["bots"]["skill"]["bones"] = "j_head"; // a list of comma seperated bones the bot will aim at + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; // a factor of how much ads to reduce when adsing + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; // a factor of how much more aimspeed delay to add + + self.pers["bots"]["behavior"] = []; + self.pers["bots"]["behavior"]["strafe"] = 50; // percentage of how often the bot strafes a target + self.pers["bots"]["behavior"]["nade"] = 50; // percentage of how often the bot will grenade + self.pers["bots"]["behavior"]["sprint"] = 50; // percentage of how often the bot will sprint + self.pers["bots"]["behavior"]["camp"] = 50; // percentage of how often the bot will camp + self.pers["bots"]["behavior"]["follow"] = 50; // percentage of how often the bot will follow + self.pers["bots"]["behavior"]["crouch"] = 10; // percentage of how often the bot will crouch + self.pers["bots"]["behavior"]["switch"] = 1; // percentage of how often the bot will switch weapons + self.pers["bots"]["behavior"]["jump"] = 100; // percentage of how often the bot will jumpshot and dropshot + + self.pers["bots"]["behavior"]["quickscope"] = false; // is a quickscoper + self.pers["bots"]["behavior"]["initswitch"] = 10; // percentage of how often the bot will switch weapons on spawn +} + +/* + We clear all of the script variables and other stuff for the bots. +*/ +resetBotVars() +{ + self.bot.script_target = undefined; + self.bot.script_target_offset = undefined; + self.bot.target = undefined; + self.bot.targets = []; + self.bot.target_this_frame = undefined; + self.bot.after_target = undefined; + self.bot.after_target_pos = undefined; + self.bot.moveto = self.origin; + + self.bot.script_aimpos = undefined; + + self.bot.script_goal = undefined; + self.bot.script_goal_dist = 0.0; + + self.bot.next_wp = -1; + self.bot.second_next_wp = -1; + self.bot.towards_goal = undefined; + self.bot.astar = []; + self.bot.stop_move = false; + self.bot.climbing = false; + self.bot.wantsprint = false; + self.bot.last_next_wp = -1; + self.bot.last_second_next_wp = -1; + + self.bot.isfrozen = false; + self.bot.sprintendtime = -1; + self.bot.isreloading = false; + self.bot.issprinting = false; + self.bot.isfragging = false; + self.bot.issmoking = false; + self.bot.isfraggingafter = false; + 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; + self.bot.last_fire_time = -1; + + self.bot.is_cur_full_auto = false; + self.bot.cur_weap_dist_multi = 1; + self.bot.is_cur_sniper = false; + + self.bot.prio_objective = false; + + self.bot.rand = randomint( 100 ); + + self BotBuiltinBotStop(); +} + +/* + The callback hook when the bot gets damaged. +*/ +onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ) +{ +} + +/* + When a bot connects to the game. + This is called when a bot is added and when multiround gamemode starts. +*/ +connected() +{ + self endon( "disconnect" ); + + self.bot = spawnstruct(); + self resetBotVars(); + + self thread onPlayerSpawned(); +} + +/* + When the bot spawns. +*/ +onPlayerSpawned() +{ + self endon( "disconnect" ); + + for ( ;; ) + { + self waittill( "spawned_player" ); + + self resetBotVars(); + self thread onWeaponChange(); + + self thread reload_watch(); + self thread sprint_watch(); + + self thread spawned(); + } +} + +/* + Is the weap a sniper +*/ +IsWeapSniper( weap ) +{ + if ( weap == "none" ) + return false; + + if ( false /*maps\mp\gametypes\_missions::getWeaponClass( weap ) != "weapon_sniper"*/ ) + return false; + + return true; +} + +/* + When the bot changes weapon. +*/ +onWeaponChange() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + first = true; + + for ( ;; ) + { + newWeapon = undefined; + + if ( first ) + { + first = false; + newWeapon = self getcurrentweapon(); + } + else + self waittill( "weapon_change", newWeapon ); + + self.bot.is_cur_full_auto = WeaponIsFullAuto( newWeapon ); + self.bot.cur_weap_dist_multi = SetWeaponDistMulti( newWeapon ); + self.bot.is_cur_sniper = IsWeapSniper( newWeapon ); + } +} + +/* + Sets the factor of distance for a weapon +*/ +SetWeaponDistMulti( weap ) +{ + if ( weap == "none" ) + return 1; + + switch ( weaponclass( weap ) ) + { + case "rifle": + return 0.9; + + case "smg": + return 0.7; + + case "pistol": + return 0.5; + + default: + return 1; + } +} + +/* + Update's the bot if it is reloading. +*/ +reload_watch() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + self waittill( "reload_start" ); + + self reload_watch_loop(); + } +} + +/* + Update's the bot if it is reloading. +*/ +reload_watch_loop() +{ + self.bot.isreloading = true; + + while ( true ) + { + ret = self waittill_any_timeout( 7.5, "reload" ); + + if ( ret == "timeout" ) + break; + + weap = self getcurrentweapon(); + + if ( weap == "none" ) + break; + + if ( self getweaponammoclip( weap ) >= weaponclipsize( weap ) ) + break; + } + + self.bot.isreloading = false; +} + +/* + Updates the bot if it is sprinting. +*/ +sprint_watch() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + self waittill( "sprint_begin" ); + self.bot.issprinting = true; + self waittill( "sprint_end" ); + self.bot.issprinting = false; + self.bot.sprintendtime = gettime(); + } +} + +/* + We wait for a time defined by the bot's difficulty and start all threads that control the bot. +*/ +spawned() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + wait self.pers["bots"]["skill"]["spawn_time"]; + + self thread doBotMovement(); + self thread walk(); + self thread target(); + self thread target_cleanup(); + self thread updateBones(); + self thread aim(); + self thread watchHoldBreath(); + self thread stance(); + self thread onNewEnemy(); + self thread check_reload(); + + self notify( "bot_spawned" ); +} + +/* + When the bot gets a new enemy. +*/ +onNewEnemy() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + self waittill( "new_enemy" ); + + if ( !isdefined( self.bot.target ) ) + continue; + + if ( !isdefined( self.bot.target.entity ) || !isai( self.bot.target.entity ) ) + continue; + + if ( self.bot.target.didlook ) + continue; + + self thread watchToLook(); + } +} + +/* + Bots will jump or dropshot their enemy player. +*/ +watchToLook() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "new_enemy" ); + + for ( ;; ) + { + while ( isdefined( self.bot.target ) && self.bot.target.didlook ) + wait 0.05; + + while ( isdefined( self.bot.target ) && self.bot.target.no_trace_time ) + wait 0.05; + + if ( !isdefined( self.bot.target ) ) + break; + + self.bot.target.didlook = true; + + if ( self.bot.isfrozen ) + continue; + + if ( self.bot.target.dist > level.bots_maxshotgundistance * 2 ) + continue; + + if ( self.bot.target.dist <= level.bots_maxknifedistance ) + continue; + + if ( !self canFire( self getcurrentweapon() ) ) + continue; + + if ( !self isInRange( self.bot.target.dist, self getcurrentweapon() ) ) + continue; + + if ( self.bot.is_cur_sniper ) + continue; + + if ( randomint( 100 ) > self.pers["bots"]["behavior"]["jump"] ) + continue; + + if ( !getdvarint( "bots_play_jumpdrop" ) ) + continue; + + if ( isdefined( self.bot.jump_time ) && gettime() - self.bot.jump_time <= 5000 ) + continue; + + if ( self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"] ) + { + if ( self getstance() != "stand" ) + continue; + + self.bot.jump_time = gettime(); + self jump(); + } + else + { + if ( getConeDot( self.bot.target.last_seen_pos, self.origin, self getplayerangles() ) < 0.8 || self.bot.target.dist <= level.bots_noadsdistance ) + continue; + + self.bot.jump_time = gettime(); + self prone(); + self notify( "kill_goal" ); + wait 2.5; + self crouch(); + } + } +} + +/* + Bots will update its needed stance according to the nodes on the level. Will also allow the bot to sprint when it can. +*/ +stance_loop() +{ + self.bot.climbing = false; + + if ( self.bot.isfrozen ) + return; + + toStance = "stand"; + + if ( self.bot.next_wp != -1 ) + toStance = level.waypoints[self.bot.next_wp].type; + + if ( !isdefined( toStance ) ) + toStance = "stand"; + + if ( toStance == "stand" && randomint( 100 ) <= self.pers["bots"]["behavior"]["crouch"] ) + toStance = "crouch"; + + if ( toStance == "climb" ) + { + self.bot.climbing = true; + toStance = "stand"; + } + + if ( toStance != "stand" && toStance != "crouch" && toStance != "prone" ) + toStance = "crouch"; + + toStance = "stand"; //Hack to make the bots never crouch + + if ( toStance == "stand" ) + self stand(); + else if ( toStance == "crouch" ) + self crouch(); + else + self prone(); + + curweap = self getcurrentweapon(); + time = gettime(); + chance = self.pers["bots"]["behavior"]["sprint"]; + + if ( time - self.lastspawntime < 5000 ) + chance *= 2; + + if ( isdefined( self.bot.script_goal ) && distancesquared( self.origin, self.bot.script_goal ) > 256 * 256 ) + chance *= 2; + + if ( toStance != "stand" || self.bot.isreloading || self.bot.issprinting || self.bot.isfraggingafter || self.bot.issmokingafter ) + return; + + if ( randomint( 100 ) > chance ) + return; + + if ( isdefined( self.bot.target ) && self canFire( curweap ) && self isInRange( self.bot.target.dist, curweap ) ) + return; + + if ( self.bot.sprintendtime != -1 && time - self.bot.sprintendtime < 2000 ) + return; + + if ( !isdefined( self.bot.towards_goal ) || distancesquared( self.origin, physicstrace( self geteye(), self geteye() + anglestoforward( self getplayerangles() ) * 1024, false, undefined ) ) < level.bots_minsprintdistance || getConeDot( self.bot.towards_goal, self.origin, self getplayerangles() ) < 0.75 ) + return; + + self thread sprint(); + self thread setBotWantSprint(); +} + +/* + Stops the sprint fix when goal is completed +*/ +setBotWantSprint() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + self notify( "setBotWantSprint" ); + self endon( "setBotWantSprint" ); + + self.bot.wantsprint = true; + + self waittill_notify_or_timeout( "kill_goal", 10 ); + + self.bot.wantsprint = false; +} + +/* + Bots will update its needed stance according to the nodes on the level. Will also allow the bot to sprint when it can. +*/ +stance() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + self waittill_either( "finished_static_waypoints", "new_static_waypoint" ); + + self stance_loop(); + } +} + +/* + Bot will wait until firing. +*/ +check_reload() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + self waittill_notify_or_timeout( "weapon_fired", 5 ); + self thread reload_thread(); + } +} + +/* + Bot will reload after firing if needed. +*/ +reload_thread() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "weapon_fired" ); + + wait 2.5; + + if ( isdefined( self.bot.target ) || self.bot.isreloading || self.bot.isfraggingafter || self.bot.issmokingafter || self.bot.isfrozen ) + return; + + cur = self getcurrentweapon(); + + if ( cur == "" || cur == "none" ) + return; + + if ( isweaponcliponly( cur ) || !self getweaponammostock( cur ) ) + return; + + maxsize = weaponclipsize( cur ); + cursize = self getweaponammoclip( cur ); + + if ( cursize / maxsize < 0.5 ) + self thread reload(); +} + +target_cleanup() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + while ( true ) + { + wait 10; + curTime = gettime(); + targetKeys = getarraykeys( self.bot.targets ); + + for ( i = 0; i < targetKeys.size; i++ ) + { + obj = self.bot.targets[ targetKeys[ i ] ]; + + if ( ( curTime - obj.time ) > 30000 ) + { + self.bot.targets[ targetKeys[ i ] ] = undefined; + } + } + } +} + +/* + The hold breath thread. +*/ +watchHoldBreath() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + wait 1; + + if ( self.bot.isfrozen ) + continue; + + self holdbreath( self playerads() > 0 ); + } +} + +/* + Bot moves towards the point +*/ +doBotMovement() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + data = spawnstruct(); + data.wasmantling = false; + + for ( data.i = 0; true; data.i += 0.05 ) + { + wait 0.05; + + waittillframeend; + self doBotMovement_loop( data ); + } +} + +/* + Bot moves towards the point +*/ +doBotMovement_loop( data ) +{ + move_To = self.bot.moveto; + angles = self getplayerangles(); + dir = ( 0, 0, 0 ); + + if ( distancesquared( self.origin, move_To ) >= 49 ) + { + cosa = cos( 0 - angles[1] ); + sina = sin( 0 - angles[1] ); + + // get the direction + dir = move_To - self.origin; + + // rotate our direction according to our angles + dir = ( dir[0] * cosa - dir[1] * sina, + dir[0] * sina + dir[1] * cosa, + 0 ); + + // make the length 127 + dir = vectornormalize( dir ) * 127; + + // invert the second component as the engine requires this + dir = ( dir[0], 0 - dir[1], 0 ); + } + + startPos = self.origin + ( 0, 0, 50 ); + startPosForward = startPos + anglestoforward( ( 0, angles[1], 0 ) ) * 25; + bt = bullettrace( startPos, startPosForward, false, self ); + + if ( bt["fraction"] >= 1 ) + { + // check if need to jump + bt = bullettrace( startPosForward, startPosForward - ( 0, 0, 40 ), false, self ); + + if ( bt["fraction"] < 1 && bt["normal"][2] > 0.9 && data.i > 1.5 ) + { + data.i = 0; + self thread jump(); + } + } + // check if need to knife glass + else if ( bt["surfacetype"] == "glass" ) + { + if ( data.i > 1.5 ) + { + data.i = 0; + self thread knife(); + } + } + else + { + // check if need to crouch + if ( bullettracepassed( startPos - ( 0, 0, 25 ), startPosForward - ( 0, 0, 25 ), false, self ) && !self.bot.climbing ) + self crouch(); + } + + // move! + 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] ) ); +} + +/* + Bots will look at the pos +*/ +bot_lookat( pos, time, vel, doAimPredict ) +{ + self notify( "bots_aim_overlap" ); + self endon( "bots_aim_overlap" ); + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "spawned_player" ); + level endon ( "intermission" ); + + if ( ( isdefined( level.intermission ) && level.intermission ) || self.bot.isfrozen || !getdvarint( "bots_play_aim" ) ) + return; + + if ( !isdefined( pos ) ) + return; + + if ( !isdefined( doAimPredict ) ) + doAimPredict = false; + + if ( !isdefined( time ) ) + time = 0.05; + + if ( !isdefined( vel ) ) + vel = ( 0, 0, 0 ); + + steps = int( time * 20 ); + + if ( steps < 1 ) + steps = 1; + + myEye = self geteye(); // get our eye pos + + if ( doAimPredict ) + { + myEye += ( self getvelocity() * 0.05 ) * ( steps - 1 ); // account for our velocity + + pos += ( vel * 0.05 ) * ( steps - 1 ); // add the velocity vector + } + + myAngle = self getplayerangles(); + angles = vectortoangles( ( pos - myEye ) - anglestoforward( myAngle ) ); + + X = angleclamp180( angles[0] - myAngle[0] ); + X = X / steps; + + Y = angleclamp180( angles[1] - myAngle[1] ); + Y = Y / steps; + + for ( i = 0; i < steps; i++ ) + { + myAngle = ( angleclamp180( myAngle[0] + X ), angleclamp180( myAngle[1] + Y ), 0 ); + self setplayerangles( myAngle ); + wait 0.05; + } +} + +/* + Returns true if the bot can fire their current weapon. +*/ +canFire( curweap ) +{ + if ( curweap == "none" ) + return false; + + return self getweaponammoclip( curweap ); +} + +/* + Returns true if the bot is in range of their target. +*/ +isInRange( dist, curweap ) +{ + if ( curweap == "none" ) + return false; + + weapclass = weaponclass( curweap ); + + if ( weapclass == "spread" && dist > level.bots_maxshotgundistance ) + return false; + + if ( curweap == "m2_flamethrower_mp" && dist > level.bots_maxshotgundistance ) + return false; + + return true; +} + +/* + Returns true if the bot can ads their current gun. +*/ +canAds( dist, curweap ) +{ + if ( curweap == "none" ) + return false; + + if ( !getdvarint( "bots_play_ads" ) ) + return false; + + far = level.bots_noadsdistance; + + if ( self hasperk( "specialty_bulletaccuracy" ) ) + far *= 1.4; + + if ( dist < far ) + return false; + + weapclass = ( weaponclass( curweap ) ); + + if ( weapclass == "spread" || weapclass == "grenade" ) + return false; + + return true; +} + +/* + The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets. +*/ +target_loop() +{ + myEye = self geteye(); + theTime = gettime(); + myAngles = self getplayerangles(); + myFov = self.pers["bots"]["skill"]["fov"]; + bestTargets = []; + bestTime = 2147483647; + rememberTime = self.pers["bots"]["skill"]["remember_time"]; + initReactTime = self.pers["bots"]["skill"]["init_react_time"]; + hasTarget = isdefined( self.bot.target ); + adsAmount = self playerads(); + adsFovFact = self.pers["bots"]["skill"]["ads_fov_multi"]; + + if ( hasTarget && !isdefined( self.bot.target.entity ) ) + { + self.bot.target = undefined; + hasTarget = false; + } + + // reduce fov if ads'ing + if ( adsAmount > 0 ) + { + myFov *= 1 - adsFovFact * adsAmount; + } + + enemies = getaispeciesarray( "axis", "all" ); + + enemycount = enemies.size; + + for ( i = -1; i < enemycount; i++ ) + { + obj = undefined; + + if ( i == -1 ) + { + if ( !isdefined( self.bot.script_target ) ) + continue; + + ent = self.bot.script_target; + key = ent getentitynumber() + ""; + daDist = distancesquared( self.origin, ent.origin ); + obj = self.bot.targets[key]; + isObjDef = isdefined( obj ); + entOrigin = ent.origin; + + if ( isdefined( self.bot.script_target_offset ) ) + entOrigin += self.bot.script_target_offset; + + if ( bullettracepassed( myEye, entOrigin, false, ent ) ) + { + if ( !isObjDef ) + { + obj = self createTargetObj( ent, theTime ); + obj.offset = self.bot.script_target_offset; + + self.bot.targets[key] = obj; + } + + self targetObjUpdateTraced( obj, daDist, ent, theTime, true ); + } + else + { + if ( !isObjDef ) + continue; + + self targetObjUpdateNoTrace( obj ); + + if ( obj.no_trace_time > rememberTime ) + { + self.bot.targets[key] = undefined; + continue; + } + } + } + else + { + enemy = enemies[i]; + + key = enemy getentitynumber() + ""; + obj = self.bot.targets[key]; + daDist = distancesquared( self.origin, enemy.origin ); + isObjDef = isdefined( obj ); + + targetHead = undefined; + targetAnkleLeft = undefined; + targetAnkleRight = undefined; + + if ( enemy targetIsDog() ) + { + targetHead = enemy gettagorigin( "j_head" ); + targetAnkleLeft = enemy gettagorigin( "j_ankle_le" ); + targetAnkleRight = enemy gettagorigin( "j_ankle_ri" ); + } + else if ( !enemy targetIsGibbed() ) + { + targetHead = enemy gettagorigin( "j_head" ); + targetAnkleLeft = enemy gettagorigin( "j_ankle_le" ); + targetAnkleRight = enemy gettagorigin( "j_ankle_ri" ); + } + else + { + targetHead = enemy gettagorigin( "j_spinelower" ); + targetAnkleLeft = enemy gettagorigin( "j_spinelower" ); + targetAnkleRight = enemy gettagorigin( "j_spinelower" ); + } + + traceHead = bullettrace( myEye, targetHead, false, enemy ); + traceAnkleLeft = bullettrace( myEye, targetAnkleLeft, false, enemy ); + traceAnkleRight = bullettrace( myEye, targetAnkleRight, false, enemy ); + + canTargetEnemy = ( ( sighttracepassed( myEye, targetHead, false, enemy ) || + sighttracepassed( myEye, targetAnkleLeft, false, enemy ) || + sighttracepassed( myEye, targetAnkleRight, false, enemy ) ) + + && ( ( traceHead["fraction"] >= 1.0 || traceHead["surfacetype"] == "glass" ) || + ( traceAnkleLeft["fraction"] >= 1.0 || traceAnkleLeft["surfacetype"] == "glass" ) || + ( traceAnkleRight["fraction"] >= 1.0 || traceAnkleRight["surfacetype"] == "glass" ) ) + + && ( getConeDot( enemy.origin, self.origin, myAngles ) >= myFov || + ( isObjDef && obj.trace_time ) ) + + && ( !isdefined( enemy.magic_bullet_shield ) || !enemy.magic_bullet_shield ) ); + + if ( isdefined( self.bot.target_this_frame ) && self.bot.target_this_frame == enemy ) + { + self.bot.target_this_frame = undefined; + + canTargetEnemy = true; + } + + if ( canTargetEnemy ) + { + if ( !isObjDef ) + { + obj = self createTargetObj( enemy, theTime ); + + self.bot.targets[key] = obj; + } + + self targetObjUpdateTraced( obj, daDist, enemy, theTime, false ); + } + else + { + if ( !isObjDef ) + continue; + + self targetObjUpdateNoTrace( obj ); + + if ( obj.no_trace_time > rememberTime ) + { + self.bot.targets[key] = undefined; + continue; + } + } + } + + if ( !isdefined( obj ) ) + continue; + + if ( theTime - obj.time < initReactTime ) + continue; + + timeDiff = theTime - obj.trace_time_time; + + if ( timeDiff < bestTime ) + { + bestTargets = []; + bestTime = timeDiff; + } + + if ( timeDiff == bestTime ) + bestTargets[key] = obj; + } + + if ( hasTarget && isdefined( bestTargets[self.bot.target.entity getentitynumber() + ""] ) ) + return; + + closest = 2147483647; + toBeTarget = undefined; + + bestKeys = getarraykeys( bestTargets ); + + for ( i = bestKeys.size - 1; i >= 0; i-- ) + { + theDist = bestTargets[bestKeys[i]].dist; + + if ( theDist > closest ) + continue; + + closest = theDist; + toBeTarget = bestTargets[bestKeys[i]]; + } + + beforeTargetID = -1; + newTargetID = -1; + + if ( hasTarget && isdefined( self.bot.target.entity ) ) + beforeTargetID = self.bot.target.entity getentitynumber(); + + if ( isdefined( toBeTarget ) && isdefined( toBeTarget.entity ) ) + newTargetID = toBeTarget.entity getentitynumber(); + + if ( beforeTargetID != newTargetID ) + { + self.bot.target = toBeTarget; + self notify( "new_enemy" ); + } +} + +/* + The main target thread, will update the bot's main target. Will auto target enemy players and handle script targets. +*/ +target() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + wait 0.05; + + self target_loop(); + } +} + +/* + Picks a valid bone for enemy +*/ + +selectBoneForTarget( enemy, bones ) +{ + if ( enemy targetIsDog() ) + { + return "j_head"; + } + else if ( !enemy targetIsGibbed() ) + { + return PickRandom( bones ); + } + else + { + return "j_spineupper"; + } +} + +/* + Updates the bot's target bone +*/ +updateBones() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + bones = strtok( self.pers["bots"]["skill"]["bones"], "," ); + waittime = self.pers["bots"]["skill"]["bone_update_interval"]; + + for ( ;; ) + { + self waittill_notify_or_timeout( "new_enemy", waittime ); + + if ( !isdefined( self.bot.target ) || !isdefined( self.bot.target.entity ) ) + continue; + + self.bot.target.bone = selectBoneForTarget( self.bot.target.entity, bones ); + } +} + +/* + Creates the base target obj +*/ +createTargetObj( ent, theTime ) +{ + obj = spawnstruct(); + obj.entity = ent; + obj.last_seen_pos = ( 0, 0, 0 ); + obj.dist = 0; + obj.time = theTime; + obj.trace_time = 0; + obj.no_trace_time = 0; + obj.trace_time_time = 0; + obj.rand = randomint( 100 ); + obj.didlook = false; + obj.offset = undefined; + obj.bone = undefined; + obj.aim_offset = undefined; + obj.aim_offset_base = undefined; + + return obj; +} + +/* + Updates the target object's difficulty missing aim, inaccurate shots +*/ +updateAimOffset( obj ) +{ + if ( !isdefined( obj.aim_offset_base ) ) + { + diffAimAmount = self.pers["bots"]["skill"]["aim_offset_amount"]; + + if ( diffAimAmount > 0 ) + obj.aim_offset_base = ( randomfloatrange( 0 - diffAimAmount, diffAimAmount ), + randomfloatrange( 0 - diffAimAmount, diffAimAmount ), + randomfloatrange( 0 - diffAimAmount, diffAimAmount ) ); + else + obj.aim_offset_base = ( 0, 0, 0 ); + } + + aimDiffTime = self.pers["bots"]["skill"]["aim_offset_time"] * 1000; + objCreatedFor = obj.trace_time; + + if ( objCreatedFor >= aimDiffTime ) + offsetScalar = 0; + else + offsetScalar = 1 - objCreatedFor / aimDiffTime; + + obj.aim_offset = obj.aim_offset_base * offsetScalar; +} + +/* + Updates the target object to be traced Has LOS +*/ +targetObjUpdateTraced( obj, daDist, ent, theTime, isScriptObj ) +{ + distClose = self.pers["bots"]["skill"]["dist_start"]; + distClose *= self.bot.cur_weap_dist_multi; + distClose *= distClose; + + distMax = self.pers["bots"]["skill"]["dist_max"]; + distMax *= self.bot.cur_weap_dist_multi; + distMax *= distMax; + + timeMulti = 1; + + if ( !isScriptObj ) + { + if ( daDist > distMax ) + timeMulti = 0; + else if ( daDist > distClose ) + timeMulti = 1 - ( ( daDist - distClose ) / ( distMax - distClose ) ); + } + + obj.no_trace_time = 0; + obj.trace_time += int( 50 * timeMulti ); + obj.dist = daDist; + obj.last_seen_pos = ent.origin; + obj.trace_time_time = theTime; + + self updateAimOffset( obj ); +} + +/* + Updates the target object to be not traced No LOS +*/ +targetObjUpdateNoTrace( obj ) +{ + obj.no_trace_time += 50; + obj.trace_time = 0; + obj.didlook = false; +} + +/* + Assigns the bot's after target (bot will keep firing at a target after no sight or death) +*/ +start_bot_after_target( who ) +{ + self endon( "disconnect" ); + self endon( "death" ); + + self.bot.after_target = who; + self.bot.after_target_pos = who.origin; + + self notify( "kill_after_target" ); + self endon( "kill_after_target" ); + + wait self.pers["bots"]["skill"]["shoot_after_time"]; + + self.bot.after_target = undefined; +} + +/* + Clears the bot's after target +*/ +clear_bot_after_target() +{ + self.bot.after_target = undefined; + self notify( "kill_after_target" ); +} + +/* + This is the bot's main aimming thread. The bot will aim at its targets or a node its going towards. Bots will aim, fire, ads, grenade. +*/ +aim_loop() +{ + aimspeed = self.pers["bots"]["skill"]["aim_time"]; + + eyePos = self geteye(); + curweap = self getcurrentweapon(); + angles = self getplayerangles(); + adsAmount = self playerads(); + adsAimSpeedFact = self.pers["bots"]["skill"]["ads_aimspeed_multi"]; + + // reduce aimspeed if ads'ing + if ( adsAmount > 0 ) + { + aimspeed *= 1 + adsAimSpeedFact * adsAmount; + } + + if ( isdefined( self.bot.target ) && isdefined( self.bot.target.entity ) && !( self.bot.prio_objective && isdefined( self.bot.script_aimpos ) ) ) + { + no_trace_time = self.bot.target.no_trace_time; + no_trace_look_time = self.pers["bots"]["skill"]["no_trace_look_time"]; + + if ( no_trace_time <= no_trace_look_time ) + { + trace_time = self.bot.target.trace_time; + last_pos = self.bot.target.last_seen_pos; + target = self.bot.target.entity; + conedot = 0; + isact = isai( self.bot.target.entity ); + + offset = self.bot.target.offset; + + if ( !isdefined( offset ) ) + offset = ( 0, 0, 0 ); + + aimoffset = self.bot.target.aim_offset; + + if ( !isdefined( aimoffset ) ) + aimoffset = ( 0, 0, 0 ); + + dist = self.bot.target.dist; + rand = self.bot.target.rand; + no_trace_ads_time = self.pers["bots"]["skill"]["no_trace_ads_time"]; + reaction_time = self.pers["bots"]["skill"]["reaction_time"]; + nadeAimOffset = 0; + + bone = self.bot.target.bone; + + if ( !isdefined( bone ) ) + bone = "j_spineupper"; + + if ( self.bot.isfraggingafter || self.bot.issmokingafter ) + nadeAimOffset = dist / 3000; + else if ( curweap != "none" && weaponclass( curweap ) == "grenade" ) + { + if ( true /*maps\mp\gametypes\_missions::getWeaponClass( curweap ) == "weapon_projectile"*/ ) + nadeAimOffset = dist / 16000; + else + nadeAimOffset = dist / 3000; + } + + if ( no_trace_time && ( !isdefined( self.bot.after_target ) || self.bot.after_target != target ) ) + { + if ( no_trace_time > no_trace_ads_time ) + { + if ( isact ) + { + //better room to nade? cook time function with dist? + if ( !self.bot.isfraggingafter && !self.bot.issmokingafter ) + { + nade = self getValidGrenade(); + + if ( isdefined( nade ) && rand <= self.pers["bots"]["behavior"]["nade"] && bullettracepassed( eyePos, eyePos + ( 0, 0, 75 ), false, self ) && bullettracepassed( last_pos, last_pos + ( 0, 0, 100 ), false, target ) && dist > level.bots_mingrenadedistance && dist < level.bots_maxgrenadedistance && getdvarint( "bots_play_nade" ) ) + { + time = 0.5; + + if ( nade == "stielhandgranate" ) + time = 2; + + if ( !isSecondaryGrenade( nade ) ) + self thread frag( time ); + else + self thread smoke( time ); + + self notify( "kill_goal" ); + } + } + } + } + else + { + 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(); + } + } + + self thread bot_lookat( last_pos + ( 0, 0, self getplayerviewheight() + nadeAimOffset ), aimspeed ); + return; + } + + if ( trace_time ) + { + if ( isact ) + { + aimpos = target gettagorigin( bone ); + + if ( !isdefined( aimpos ) ) + return; + + aimpos += offset; + aimpos += aimoffset; + aimpos += ( 0, 0, nadeAimOffset ); + + conedot = getConeDot( aimpos, eyePos, angles ); + + 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 getaivelocity(), true ); + } + else + { + aimpos = target.origin; + aimpos += offset; + aimpos += aimoffset; + aimpos += ( 0, 0, nadeAimOffset ); + + conedot = getConeDot( aimpos, eyePos, angles ); + + if ( !nadeAimOffset && conedot > 0.999 && lengthsquared( aimoffset ) < 0.05 ) + self thread bot_lookat( aimpos, 0.05 ); + else + self thread bot_lookat( aimpos, aimspeed ); + } + + if ( isact && !self.bot.isknifingafter && conedot > 0.9 && dist < level.bots_maxknifedistance && trace_time > reaction_time && !self.bot.isreloading && getdvarint( "bots_play_knife" ) ) + { + self clear_bot_after_target(); + self thread knife( target ); + return; + } + + if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) + return; + + canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); + + if ( canADS ) + { + stopAdsOverride = false; + + if ( self.bot.is_cur_sniper ) + { + if ( self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && gettime() - self.bot.last_fire_time < 1000 ) + stopAdsOverride = true; + else + self notify( "kill_goal" ); + } + + if ( !stopAdsOverride ) + self thread pressADS(); + } + + if ( trace_time > reaction_time ) + { + if ( ( !canADS || adsAmount >= 1.0 || self inLastStand() || self getstance() == "prone" ) && ( conedot > 0.99 || dist < level.bots_maxknifedistance ) && getdvarint( "bots_play_fire" ) ) + self botFire(); + + if ( isact ) + self thread start_bot_after_target( target ); + } + + return; + } + } + } + + if ( isdefined( self.bot.after_target ) ) + { + nadeAimOffset = 0; + last_pos = self.bot.after_target_pos; + dist = distancesquared( self.origin, last_pos ); + + if ( self.bot.isfraggingafter || self.bot.issmokingafter ) + nadeAimOffset = dist / 3000; + else if ( curweap != "none" && weaponclass( curweap ) == "grenade" ) + { + if ( true /*maps\mp\gametypes\_missions::getWeaponClass( curweap ) == "weapon_projectile"*/ ) + nadeAimOffset = dist / 16000; + else + nadeAimOffset = dist / 3000; + } + + aimpos = last_pos + ( 0, 0, self getplayerviewheight() + nadeAimOffset ); + conedot = getConeDot( aimpos, eyePos, angles ); + + self thread bot_lookat( aimpos, aimspeed ); + + if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) + return; + + canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); + + if ( canADS ) + { + stopAdsOverride = false; + + if ( self.bot.is_cur_sniper ) + { + if ( self.pers["bots"]["behavior"]["quickscope"] && self.bot.last_fire_time != -1 && gettime() - self.bot.last_fire_time < 1000 ) + stopAdsOverride = true; + else + self notify( "kill_goal" ); + } + + if ( !stopAdsOverride ) + self thread pressADS(); + } + + if ( ( !canADS || adsAmount >= 1.0 || self inLastStand() || self getstance() == "prone" ) && ( conedot > 0.95 || dist < level.bots_maxknifedistance ) && getdvarint( "bots_play_fire" ) ) + self botFire(); + + return; + } + + if ( self.bot.next_wp != -1 && isdefined( level.waypoints[self.bot.next_wp].angles ) && false ) + { + forwardPos = anglestoforward( level.waypoints[self.bot.next_wp].angles ) * 1024; + + self thread bot_lookat( eyePos + forwardPos, aimspeed ); + } + else if ( isdefined( self.bot.script_aimpos ) ) + { + self thread bot_lookat( self.bot.script_aimpos, aimspeed ); + } + else + { + lookat = undefined; + + if ( self.bot.second_next_wp != -1 && !self.bot.issprinting && !self.bot.climbing ) + lookat = level.waypoints[self.bot.second_next_wp].origin; + else if ( isdefined( self.bot.towards_goal ) ) + lookat = self.bot.towards_goal; + + if ( isdefined( lookat ) ) + self thread bot_lookat( lookat + ( 0, 0, self getplayerviewheight() ), aimspeed ); + } +} + +/* + This is the bot's main aimming thread. The bot will aim at its targets or a node its going towards. Bots will aim, fire, ads, grenade. +*/ +aim() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + wait 0.05; + + if ( ( isdefined( level.intermission ) && level.intermission ) || self.bot.isfrozen ) + continue; + + self aim_loop(); + } +} + +/* + This is the main walking logic for the bot. +*/ +walk() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + wait 0.05; + + self botSetMoveTo( self.origin ); + + if ( !getdvarint( "bots_play_move" ) ) + continue; + + if ( ( isdefined( level.intermission ) && level.intermission ) || self.bot.isfrozen || self.bot.stop_move ) + continue; + + self walk_loop(); + } +} + +/* + This is the main walking logic for the bot. +*/ +walk_loop() +{ + shouldTarget = isdefined( self.bot.target ) && isdefined( self.bot.target.entity ) && !self.bot.prio_objective; + + if ( shouldTarget ) + { + curweap = self getcurrentweapon(); + + if ( self.bot.isfraggingafter || self.bot.issmokingafter ) + { + return; + } + + if ( isai( self.bot.target.entity ) && self.bot.target.trace_time && self canFire( curweap ) && self isInRange( self.bot.target.dist, curweap ) ) + { + if ( self inLastStand() || self getstance() == "prone" || ( self.bot.is_cur_sniper && self playerads() > 0 ) ) + return; + + if ( self.bot.target.rand <= self.pers["bots"]["behavior"]["strafe"] ) + self strafe( self.bot.target.entity ); + + return; + } + } + + dist = 16; + + goal = self getRandomGoal(); + + isScriptGoal = false; + + if ( isdefined( self.bot.script_goal ) && !shouldTarget ) + { + goal = self.bot.script_goal; + dist = self.bot.script_goal_dist; + + isScriptGoal = true; + } + else + { + if ( shouldTarget ) + goal = self.bot.target.last_seen_pos; + + self notify( "new_goal_internal" ); + } + + self doWalk( goal, dist, isScriptGoal ); + self.bot.towards_goal = undefined; + self.bot.next_wp = -1; + self.bot.second_next_wp = -1; +} + +/* + Will walk to the given goal when dist near. Uses AStar path finding with the level's nodes. +*/ +doWalk( goal, dist, isScriptGoal ) +{ + level endon( "intermission" ); + self endon( "kill_goal" ); + self endon( "goal_internal" ); //so that the watchOnGoal notify can happen same frame, not a frame later + + dist *= dist; + + if ( isScriptGoal ) + self thread doWalkScriptNotify(); + + self thread killWalkOnEvents(); + self thread watchOnGoal( goal, dist ); + + current = self initAStar( goal ); + + path_was_truncated = ( current + 1 ) >= 32; + + if ( current <= -1 ) + { + self notify( "bad_path_internal" ); + return; + } + + // skip waypoints we already completed to prevent rubber banding + if ( current > 0 && self.bot.astar[current] == self.bot.last_next_wp && self.bot.astar[current - 1] == self.bot.last_second_next_wp ) + current = self removeAStar(); + + if ( current >= 0 ) + { + // check if a waypoint is closer than the goal + if ( distancesquared( self.origin, level.waypoints[self.bot.astar[current]].origin ) < distancesquared( self.origin, goal ) || distancesquared( level.waypoints[self.bot.astar[current]].origin, playerphysicstrace( self.origin + ( 0, 0, 32 ), level.waypoints[self.bot.astar[current]].origin ) ) > 1.0 ) + { + while ( current >= 0 ) + { + self.bot.next_wp = self.bot.astar[current]; + self.bot.second_next_wp = -1; + + if ( current > 0 ) + self.bot.second_next_wp = self.bot.astar[current - 1]; + + self notify( "new_static_waypoint" ); + + self movetowards( level.waypoints[self.bot.next_wp].origin ); + self.bot.last_next_wp = self.bot.next_wp; + self.bot.last_second_next_wp = self.bot.second_next_wp; + + current = self removeAStar(); + } + } + } + + if ( path_was_truncated ) + { + self notify( "kill_goal" ); + return; + } + + self.bot.next_wp = -1; + self.bot.second_next_wp = -1; + self notify( "finished_static_waypoints" ); + + if ( distancesquared( self.origin, goal ) > dist ) + { + self.bot.last_next_wp = -1; + self.bot.last_second_next_wp = -1; + self movetowards( goal ); // any better way?? + } + + self notify( "finished_goal" ); + + wait 1; + + if ( distancesquared( self.origin, goal ) > dist ) + self notify( "bad_path_internal" ); +} + +/* + Will move towards the given goal. Will try to not get stuck by crouching, then jumping and then strafing around objects. +*/ +movetowards( goal ) +{ + if ( !isdefined( goal ) ) + return; + + self.bot.towards_goal = goal; + + lastOri = self.origin; + stucks = 0; + timeslow = 0; + time = 0; + + if ( self.bot.issprinting ) + tempGoalDist = level.bots_goaldistance * 2; + else + tempGoalDist = level.bots_goaldistance; + + while ( distancesquared( self.origin, goal ) > tempGoalDist ) + { + self botSetMoveTo( goal ); + + if ( time > 3000 ) + { + time = 0; + + if ( distancesquared( self.origin, lastOri ) < 32 * 32 ) + { + self thread knife(); + wait 0.5; + + stucks++; + + randomDir = self getRandomLargestStafe( stucks ); + + self BotNotifyBotEvent( "stuck" ); + + self botSetMoveTo( randomDir ); + wait stucks; + self stand(); + + self.bot.last_next_wp = -1; + self.bot.last_second_next_wp = -1; + } + + lastOri = self.origin; + } + else if ( timeslow > 0 && ( timeslow % 1000 ) == 0 ) + { + self thread doMantle(); + } + else if ( time == 2000 ) + { + if ( distancesquared( self.origin, lastOri ) < 32 * 32 ) + self crouch(); + } + else if ( time == 1750 ) + { + if ( distancesquared( self.origin, lastOri ) < 32 * 32 ) + { + // check if directly above or below + if ( abs( goal[2] - self.origin[2] ) > 64 && getConeDot( goal + ( 1, 1, 0 ), self.origin + ( -1, -1, 0 ), vectortoangles( ( goal[0], goal[1], self.origin[2] ) - self.origin ) ) < 0.64 && distancesquared2D( self.origin, goal ) < 32 * 32 ) + { + stucks = 2; + } + } + } + + wait 0.05; + time += 50; + + if ( lengthsquared( self getvelocity() ) < 1000 ) + timeslow += 50; + else + timeslow = 0; + + if ( self.bot.issprinting ) + tempGoalDist = level.bots_goaldistance * 2; + else + tempGoalDist = level.bots_goaldistance; + + if ( stucks >= 2 ) + self notify( "bad_path_internal" ); + } + + self.bot.towards_goal = undefined; + self notify( "completed_move_to" ); +} + +/* + The bot will strafe left or right from their enemy. +*/ +strafe( target ) +{ + self endon( "kill_goal" ); + self thread killWalkOnEvents(); + + angles = vectortoangles( vectornormalize( target.origin - self.origin ) ); + anglesLeft = ( 0, angles[1] + 90, 0 ); + anglesRight = ( 0, angles[1] - 90, 0 ); + + myOrg = self.origin + ( 0, 0, 16 ); + left = myOrg + anglestoforward( anglesLeft ) * 500; + right = myOrg + anglestoforward( anglesRight ) * 500; + + traceLeft = bullettrace( myOrg, left, false, self ); + traceRight = bullettrace( myOrg, right, false, self ); + + strafe = traceLeft["position"]; + + if ( traceRight["fraction"] > traceLeft["fraction"] ) + strafe = traceRight["position"]; + + self.bot.last_next_wp = -1; + self.bot.last_second_next_wp = -1; + self botSetMoveTo( strafe ); + wait 2; + self notify( "kill_goal" ); +} + +/* + Will return the pos of the largest trace from the bot. +*/ +getRandomLargestStafe( dist ) +{ + //find a better algo? + traces = NewHeap( ::HeapTraceFraction ); + myOrg = self.origin + ( 0, 0, 16 ); + + traces HeapInsert( bullettrace( myOrg, myOrg + ( -100 * dist, 0, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( 100 * dist, 0, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( 0, 100 * dist, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( 0, -100 * dist, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( -100 * dist, -100 * dist, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( -100 * dist, 100 * dist, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( 100 * dist, -100 * dist, 0 ), false, self ) ); + traces HeapInsert( bullettrace( myOrg, myOrg + ( 100 * dist, 100 * dist, 0 ), false, self ) ); + + toptraces = []; + + top = traces.data[0]; + toptraces[toptraces.size] = top; + traces HeapRemove(); + + while ( traces.data.size && top["fraction"] - traces.data[0]["fraction"] < 0.1 ) + { + toptraces[toptraces.size] = traces.data[0]; + traces HeapRemove(); + } + + return toptraces[randomint( toptraces.size )]["position"]; +} + +/* + Calls the astar search algorithm for the path to the goal. +*/ +initAStar( goal ) +{ + nodes = BotBuiltinGeneratePath( self.origin, goal, self.team ); + + if ( !isdefined( nodes ) || nodes.size <= 0 ) + { + //Try again to find a path to the origin using best effort algo + nodes = BotBuiltinGeneratePath( self.origin, goal, self.team, 192.0 ); + + if ( !isdefined( nodes ) || nodes.size <= 0 ) + { + self.bot.astar = []; + return -1; + } + } + + node_indexes = []; + + for ( i = nodes.size - 1; i >= 0; i-- ) + { + node_indexes[ node_indexes.size ] = nodes[ i ] BotBuiltinGetNodeNumber(); + } + + self.bot.astar = node_indexes; + + return self.bot.astar.size - 1; +} + +/* + Cleans up the astar nodes for one node. +*/ +removeAStar() +{ + remove = self.bot.astar.size - 1; + + self.bot.astar[remove] = undefined; + + return self.bot.astar.size - 1; +} + +/* + Does the notify for goal completion for outside scripts +*/ +doWalkScriptNotify() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "kill_goal" ); + + if ( self waittill_either_return( "goal_internal", "bad_path_internal" ) == "goal_internal" ) + self notify( "goal" ); + else + self notify( "bad_path" ); +} + +/* + Will stop the goal walk when an enemy is found or flashed or a new goal appeared for the bot. +*/ +killWalkOnEvents() +{ + self endon( "kill_goal" ); + self endon( "disconnect" ); + self endon( "zombified" ); + + self waittill_any( "new_enemy", "new_goal_internal", "goal_internal", "bad_path_internal" ); + + waittillframeend; + + self notify( "kill_goal" ); +} + +/* + Will kill the goal when the bot made it to its goal. +*/ +watchOnGoal( goal, dis ) +{ + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "kill_goal" ); + + while ( distancesquared( self.origin, goal ) > dis ) + wait 0.05; + + self notify( "goal_internal" ); +} + +/* + Bot will move towards here +*/ +botSetMoveTo( where ) +{ + self.bot.moveto = where; +} + +/* + Bot will press ADS for a time. +*/ +pressADS( time ) +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_ads" ); + self endon( "bot_ads" ); + + if ( !isdefined( time ) ) + time = 0.05; + + self BotBuiltinBotAction( "+ads" ); + + if ( time ) + wait time; + + self BotBuiltinBotAction( "-ads" ); +} + +/* + Bot will hold the frag button for a time +*/ +frag( time ) +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_frag" ); + self endon( "bot_frag" ); + + if ( !isdefined( time ) ) + time = 0.05; + + self BotBuiltinBotAction( "+frag" ); + self.bot.isfragging = true; + self.bot.isfraggingafter = true; + + if ( time ) + wait time; + + self BotBuiltinBotAction( "-frag" ); + self.bot.isfragging = false; + + wait 1.25; + self.bot.isfraggingafter = false; +} + +/* + Bot will hold breath if true or not +*/ +holdbreath( what ) +{ + if ( what ) + self BotBuiltinBotAction( "+holdbreath" ); + else + self BotBuiltinBotAction( "-holdbreath" ); +} + +/* + Bot will hold the 'smoke' button for a time. +*/ +smoke( time ) +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_smoke" ); + self endon( "bot_smoke" ); + + if ( !isdefined( time ) ) + time = 0.05; + + self BotBuiltinBotAction( "+smoke" ); + self.bot.issmoking = true; + self.bot.issmokingafter = true; + + if ( time ) + wait time; + + self BotBuiltinBotAction( "-smoke" ); + self.bot.issmoking = false; + + wait 1.25; + self.bot.issmokingafter = false; +} + +/* + Waits a time defined by their difficulty for semi auto guns (no rapid fire) +*/ +doSemiTime() +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_semi_time" ); + self endon( "bot_semi_time" ); + + self.bot.semi_time = true; + wait self.pers["bots"]["skill"]["semi_time"]; + self.bot.semi_time = false; +} + +/* + Bots will fire their gun. +*/ +botFire() +{ + self.bot.last_fire_time = gettime(); + + if ( self.bot.is_cur_full_auto ) + { + self thread pressFire(); + return; + } + + if ( self.bot.semi_time ) + return; + + self thread pressFire(); + self thread doSemiTime(); +} + +/* + Bots do the mantle +*/ +doMantle() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + self endon( "kill_goal" ); + + self jump(); + + wait 0.35; + + self jump(); +} + +/* + Bot will fire for a time. +*/ +pressFire( time ) +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_fire" ); + self endon( "bot_fire" ); + + if ( !isdefined( time ) ) + time = 0.05; + + self BotBuiltinBotAction( "+fire" ); + + if ( time ) + wait time; + + self BotBuiltinBotAction( "-fire" ); +} + +/* + Bot will reload. +*/ +reload() +{ + self endon( "death" ); + self endon( "disconnect" ); + self notify( "bot_reload" ); + self endon( "bot_reload" ); + + self BotBuiltinBotAction( "+reload" ); + wait 0.05; + self BotBuiltinBotAction( "-reload" ); +} + +/* + Performs melee target +*/ +do_knife_target( target ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self endon( "bot_knife" ); + + if ( !getdvarint( "aim_automelee_enabled" ) || !self isonground() || self getstance() == "prone" || self inLastStand() ) + { + self.bot.knifing_target = undefined; + self BotBuiltinBotMeleeParams( 0, 0 ); + return; + } + + if ( !isdefined( target ) || ( !isplayer( target ) && !isai( 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( target ) +{ + self endon( "zombified" ); + 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; + + self BotBuiltinBotAction( "+melee" ); + wait 0.05; + self BotBuiltinBotAction( "-melee" ); + + self.bot.isknifing = false; + + wait 1; + + self.bot.isknifingafter = false; +} + +/* + Bot will press use for a time. +*/ +use( time ) +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_use" ); + self endon( "bot_use" ); + + if ( !isdefined( time ) ) + time = 0.05; + + self BotBuiltinBotAction( "+activate" ); + + if ( time ) + wait time; + + self BotBuiltinBotAction( "-activate" ); +} + +/* + Bot will jump. +*/ +jump() +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_jump" ); + self endon( "bot_jump" ); + + if ( self getstance() != "stand" ) + { + self stand(); + wait 1; + } + + self BotBuiltinBotAction( "+gostand" ); + wait 0.05; + self BotBuiltinBotAction( "-gostand" ); +} + +/* + Bot will stand. +*/ +stand() +{ + self BotBuiltinBotAction( "-gocrouch" ); + self BotBuiltinBotAction( "-goprone" ); +} + +/* + Bot will crouch. +*/ +crouch() +{ + self BotBuiltinBotAction( "+gocrouch" ); + self BotBuiltinBotAction( "-goprone" ); +} + +/* + Bot will prone. +*/ +prone() +{ + self BotBuiltinBotAction( "-gocrouch" ); + self BotBuiltinBotAction( "+goprone" ); +} + +/* + Bot will sprint. +*/ +sprint() +{ + self endon( "zombified" ); + self endon( "disconnect" ); + self notify( "bot_sprint" ); + self endon( "bot_sprint" ); + + self BotBuiltinBotAction( "+sprint" ); + wait 0.05; + self BotBuiltinBotAction( "-sprint" ); +} diff --git a/maps/bots/_bot_script.gsc b/maps/bots/_bot_script.gsc index 0846924..5331db8 100644 --- a/maps/bots/_bot_script.gsc +++ b/maps/bots/_bot_script.gsc @@ -1,498 +1,498 @@ -#include common_scripts\utility; -#include maps\_utility; -#include maps\bots\_bot_utility; - -/* - Initialize bot script level functions -*/ -bot_script_init() -{ - level thread maps\bots\objectives\_manager::init(); -} - -/* - When the bot gets added into the game. -*/ -added() -{ - self endon( "disconnect" ); - - self set_diff(); -} - -/* - When the bot connects to the game. -*/ -connected() -{ - self endon( "disconnect" ); - - self thread difficulty(); - self thread onBotSpawned(); - self thread onSpawned(); - - self thread maps\bots\objectives\_manager::connected(); -} - -/* - The callback for when the bot gets damaged. -*/ -onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ) -{ - if ( !IsDefined( self ) || !isDefined( self.team ) ) - return; - - if ( !isAlive( self ) ) - return; - - if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" ) - return; - - if ( iDamage <= 0 ) - return; - - if ( !IsDefined( eAttacker ) || !isDefined( eAttacker.team ) ) - return; - - if ( eAttacker == self ) - return; - - if ( !isAlive( eAttacker ) ) - return; - - self SetAttacker( eAttacker ); -} - -/* - Updates the bot's difficulty variables. -*/ -difficulty() -{ - self endon( "disconnect" ); - - for ( ;; ) - { - if ( GetDvarInt( "bots_skill" ) != 9 ) - { - switch ( self.pers["bots"]["skill"]["base"] ) - { - case 1: - self.pers["bots"]["skill"]["aim_time"] = 0.6; - self.pers["bots"]["skill"]["init_react_time"] = 1500; - self.pers["bots"]["skill"]["reaction_time"] = 1000; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 500; - self.pers["bots"]["skill"]["no_trace_look_time"] = 600; - self.pers["bots"]["skill"]["remember_time"] = 750; - self.pers["bots"]["skill"]["fov"] = 0.7; - self.pers["bots"]["skill"]["dist_max"] = 2500; - self.pers["bots"]["skill"]["dist_start"] = 1000; - self.pers["bots"]["skill"]["spawn_time"] = 0.75; - self.pers["bots"]["skill"]["help_dist"] = 0; - self.pers["bots"]["skill"]["semi_time"] = 0.9; - self.pers["bots"]["skill"]["shoot_after_time"] = 1; - self.pers["bots"]["skill"]["aim_offset_time"] = 1.5; - self.pers["bots"]["skill"]["aim_offset_amount"] = 4; - self.pers["bots"]["skill"]["bone_update_interval"] = 2; - self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 0; - self.pers["bots"]["behavior"]["nade"] = 10; - self.pers["bots"]["behavior"]["sprint"] = 30; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 20; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 0; - break; - - case 2: - self.pers["bots"]["skill"]["aim_time"] = 0.55; - self.pers["bots"]["skill"]["init_react_time"] = 1000; - self.pers["bots"]["skill"]["reaction_time"] = 800; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; - self.pers["bots"]["skill"]["no_trace_look_time"] = 1250; - self.pers["bots"]["skill"]["remember_time"] = 1500; - self.pers["bots"]["skill"]["fov"] = 0.65; - self.pers["bots"]["skill"]["dist_max"] = 3000; - self.pers["bots"]["skill"]["dist_start"] = 1500; - self.pers["bots"]["skill"]["spawn_time"] = 0.65; - self.pers["bots"]["skill"]["help_dist"] = 500; - self.pers["bots"]["skill"]["semi_time"] = 0.75; - self.pers["bots"]["skill"]["shoot_after_time"] = 0.75; - self.pers["bots"]["skill"]["aim_offset_time"] = 1; - self.pers["bots"]["skill"]["aim_offset_amount"] = 3; - self.pers["bots"]["skill"]["bone_update_interval"] = 1.5; - self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri,j_head"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 10; - self.pers["bots"]["behavior"]["nade"] = 15; - self.pers["bots"]["behavior"]["sprint"] = 45; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 15; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 10; - break; - - case 3: - self.pers["bots"]["skill"]["aim_time"] = 0.4; - self.pers["bots"]["skill"]["init_react_time"] = 750; - self.pers["bots"]["skill"]["reaction_time"] = 500; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; - self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; - self.pers["bots"]["skill"]["remember_time"] = 2000; - self.pers["bots"]["skill"]["fov"] = 0.6; - self.pers["bots"]["skill"]["dist_max"] = 4000; - self.pers["bots"]["skill"]["dist_start"] = 2250; - self.pers["bots"]["skill"]["spawn_time"] = 0.5; - self.pers["bots"]["skill"]["help_dist"] = 750; - self.pers["bots"]["skill"]["semi_time"] = 0.65; - self.pers["bots"]["skill"]["shoot_after_time"] = 0.65; - self.pers["bots"]["skill"]["aim_offset_time"] = 0.75; - self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5; - self.pers["bots"]["skill"]["bone_update_interval"] = 1; - self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 20; - self.pers["bots"]["behavior"]["nade"] = 20; - self.pers["bots"]["behavior"]["sprint"] = 50; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 10; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 25; - break; - - case 4: - self.pers["bots"]["skill"]["aim_time"] = 0.3; - self.pers["bots"]["skill"]["init_react_time"] = 600; - self.pers["bots"]["skill"]["reaction_time"] = 400; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; - self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; - self.pers["bots"]["skill"]["remember_time"] = 3000; - self.pers["bots"]["skill"]["fov"] = 0.55; - self.pers["bots"]["skill"]["dist_max"] = 5000; - self.pers["bots"]["skill"]["dist_start"] = 3350; - self.pers["bots"]["skill"]["spawn_time"] = 0.35; - self.pers["bots"]["skill"]["help_dist"] = 1000; - self.pers["bots"]["skill"]["semi_time"] = 0.5; - self.pers["bots"]["skill"]["shoot_after_time"] = 0.5; - self.pers["bots"]["skill"]["aim_offset_time"] = 0.5; - self.pers["bots"]["skill"]["aim_offset_amount"] = 2; - self.pers["bots"]["skill"]["bone_update_interval"] = 0.75; - self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head,j_head"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 30; - self.pers["bots"]["behavior"]["nade"] = 25; - self.pers["bots"]["behavior"]["sprint"] = 55; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 10; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 35; - break; - - case 5: - self.pers["bots"]["skill"]["aim_time"] = 0.25; - self.pers["bots"]["skill"]["init_react_time"] = 500; - self.pers["bots"]["skill"]["reaction_time"] = 300; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500; - self.pers["bots"]["skill"]["no_trace_look_time"] = 2000; - self.pers["bots"]["skill"]["remember_time"] = 4000; - self.pers["bots"]["skill"]["fov"] = 0.5; - self.pers["bots"]["skill"]["dist_max"] = 7500; - self.pers["bots"]["skill"]["dist_start"] = 5000; - self.pers["bots"]["skill"]["spawn_time"] = 0.25; - self.pers["bots"]["skill"]["help_dist"] = 1500; - self.pers["bots"]["skill"]["semi_time"] = 0.4; - self.pers["bots"]["skill"]["shoot_after_time"] = 0.35; - self.pers["bots"]["skill"]["aim_offset_time"] = 0.35; - self.pers["bots"]["skill"]["aim_offset_amount"] = 1.5; - self.pers["bots"]["skill"]["bone_update_interval"] = 0.5; - self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 40; - self.pers["bots"]["behavior"]["nade"] = 35; - self.pers["bots"]["behavior"]["sprint"] = 60; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 10; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 50; - break; - - case 6: - self.pers["bots"]["skill"]["aim_time"] = 0.2; - self.pers["bots"]["skill"]["init_react_time"] = 250; - self.pers["bots"]["skill"]["reaction_time"] = 150; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000; - self.pers["bots"]["skill"]["no_trace_look_time"] = 3000; - self.pers["bots"]["skill"]["remember_time"] = 5000; - self.pers["bots"]["skill"]["fov"] = 0.45; - self.pers["bots"]["skill"]["dist_max"] = 10000; - self.pers["bots"]["skill"]["dist_start"] = 7500; - self.pers["bots"]["skill"]["spawn_time"] = 0.2; - self.pers["bots"]["skill"]["help_dist"] = 2000; - self.pers["bots"]["skill"]["semi_time"] = 0.25; - self.pers["bots"]["skill"]["shoot_after_time"] = 0.25; - self.pers["bots"]["skill"]["aim_offset_time"] = 0.25; - self.pers["bots"]["skill"]["aim_offset_amount"] = 1; - self.pers["bots"]["skill"]["bone_update_interval"] = 0.25; - self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head,j_head"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 50; - self.pers["bots"]["behavior"]["nade"] = 45; - self.pers["bots"]["behavior"]["sprint"] = 65; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 10; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 75; - break; - - case 7: - self.pers["bots"]["skill"]["aim_time"] = 0.1; - self.pers["bots"]["skill"]["init_react_time"] = 100; - self.pers["bots"]["skill"]["reaction_time"] = 50; - self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; - self.pers["bots"]["skill"]["no_trace_look_time"] = 4000; - self.pers["bots"]["skill"]["remember_time"] = 7500; - self.pers["bots"]["skill"]["fov"] = 0.4; - self.pers["bots"]["skill"]["dist_max"] = 15000; - self.pers["bots"]["skill"]["dist_start"] = 10000; - self.pers["bots"]["skill"]["spawn_time"] = 0.05; - self.pers["bots"]["skill"]["help_dist"] = 3000; - self.pers["bots"]["skill"]["semi_time"] = 0.1; - self.pers["bots"]["skill"]["shoot_after_time"] = 0; - self.pers["bots"]["skill"]["aim_offset_time"] = 0; - self.pers["bots"]["skill"]["aim_offset_amount"] = 0; - self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; - self.pers["bots"]["skill"]["bones"] = "j_head"; - self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; - self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; - - self.pers["bots"]["behavior"]["strafe"] = 65; - self.pers["bots"]["behavior"]["nade"] = 65; - self.pers["bots"]["behavior"]["sprint"] = 70; - self.pers["bots"]["behavior"]["camp"] = 5; - self.pers["bots"]["behavior"]["follow"] = 5; - self.pers["bots"]["behavior"]["crouch"] = 5; - self.pers["bots"]["behavior"]["switch"] = 2; - self.pers["bots"]["behavior"]["jump"] = 90; - break; - } - } - - wait 5; - } -} - -/* - Sets the bot difficulty. -*/ -set_diff() -{ - rankVar = GetDvarInt( "bots_skill" ); - - switch ( rankVar ) - { - case 0: - self.pers["bots"]["skill"]["base"] = Round( random_normal_distribution( 3.5, 1.75, 1, 7 ) ); - break; - - case 8: - break; - - case 9: - self.pers["bots"]["skill"]["base"] = randomIntRange( 1, 7 ); - self.pers["bots"]["skill"]["aim_time"] = 0.05 * randomIntRange( 1, 20 ); - self.pers["bots"]["skill"]["init_react_time"] = 50 * randomInt( 100 ); - self.pers["bots"]["skill"]["reaction_time"] = 50 * randomInt( 100 ); - self.pers["bots"]["skill"]["no_trace_ads_time"] = 50 * randomInt( 100 ); - self.pers["bots"]["skill"]["no_trace_look_time"] = 50 * randomInt( 100 ); - self.pers["bots"]["skill"]["remember_time"] = 50 * randomInt( 100 ); - self.pers["bots"]["skill"]["fov"] = randomFloatRange( -1, 1 ); - - randomNum = randomIntRange( 500, 25000 ); - self.pers["bots"]["skill"]["dist_start"] = randomNum; - self.pers["bots"]["skill"]["dist_max"] = randomNum * 2; - - self.pers["bots"]["skill"]["spawn_time"] = 0.05 * randomInt( 20 ); - self.pers["bots"]["skill"]["help_dist"] = randomIntRange( 500, 25000 ); - self.pers["bots"]["skill"]["semi_time"] = randomFloatRange( 0.05, 1 ); - self.pers["bots"]["skill"]["shoot_after_time"] = randomFloatRange( 0.05, 1 ); - self.pers["bots"]["skill"]["aim_offset_time"] = randomFloatRange( 0.05, 1 ); - self.pers["bots"]["skill"]["aim_offset_amount"] = randomFloatRange( 0.05, 1 ); - self.pers["bots"]["skill"]["bone_update_interval"] = randomFloatRange( 0.05, 1 ); - self.pers["bots"]["skill"]["bones"] = "j_head,j_spineupper,j_ankle_ri,j_ankle_le"; - - self.pers["bots"]["behavior"]["strafe"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["nade"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["sprint"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["camp"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["follow"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["crouch"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["switch"] = randomInt( 100 ); - self.pers["bots"]["behavior"]["jump"] = randomInt( 100 ); - break; - - default: - self.pers["bots"]["skill"]["base"] = rankVar; - break; - } -} - -/* - When the bot spawned, after the difficulty wait. Start the logic for the bot. -*/ -onBotSpawned() -{ - self endon( "disconnect" ); - level endon( "intermission" ); - - for ( ;; ) - { - self waittill( "bot_spawned" ); - - self thread start_bot_threads(); - } -} - -/* - When the bot spawns. -*/ -onSpawned() -{ - self endon( "disconnect" ); - - for ( ;; ) - { - self waittill( "spawned_player" ); - - self thread maps\bots\objectives\_manager::spawned(); - } -} - -/* - Starts all the bot thinking -*/ -start_bot_threads() -{ - self endon( "disconnect" ); - level endon( "intermission" ); - self endon( "zombified" ); - - self thread doReloadCancel(); - - self thread maps\bots\objectives\_manager::start_bot_threads(); -} - -/* - Changes to the weap -*/ -changeToWeapon( weap ) -{ - self endon( "disconnect" ); - self endon( "zombified" ); - level endon( "game_ended" ); - - if ( !self HasWeapon( weap ) ) - return false; - - self switchToWeapon( weap ); - - if ( self GetCurrentWeapon() == weap ) - return true; - - self waittill_any_timeout( 5, "weapon_change" ); - - return ( self GetCurrentWeapon() == weap ); -} - -/* - Reload cancels -*/ -doReloadCancel_loop() -{ - ret = self waittill_any_return( "reload", "weapon_change" ); - - if ( self BotIsFrozen() ) - return; - - if ( self useButtonPressed() ) - return; - - if ( self InLastStand() ) - return; - - curWeap = self GetCurrentWeapon(); - - if ( !self isWeaponPrimary( curWeap ) ) - return; - - if ( ret == "reload" ) - { - // check single reloads - if ( self GetWeaponAmmoClip( curWeap ) < WeaponClipSize( curWeap ) ) - return; - } - - // check difficulty - if ( self.pers["bots"]["skill"]["base"] <= 3 ) - return; - - // check if got another weapon - weaponslist = self GetWeaponsListPrimaries(); - weap = ""; - - while ( weaponslist.size ) - { - weapon = weaponslist[randomInt( weaponslist.size )]; - weaponslist = array_remove( weaponslist, weapon ); - - if ( !self isWeaponPrimary( weapon ) ) - continue; - - if ( curWeap == weapon || weapon == "none" || weapon == "" ) - continue; - - weap = weapon; - break; - } - - if ( weap == "" ) - return; - - // do the cancel - wait 0.1; - self thread ChangeToWeapon( weap ); - wait 0.25; - self thread ChangeToWeapon( curWeap ); - wait 2; -} - -/* - Reload cancels -*/ -doReloadCancel() -{ - self endon( "disconnect" ); - self endon( "zombified" ); - - for ( ;; ) - { - self doReloadCancel_loop(); - } -} +#include common_scripts\utility; +#include maps\_utility; +#include maps\bots\_bot_utility; + +/* + Initialize bot script level functions +*/ +bot_script_init() +{ + level thread maps\bots\objectives\_manager::init(); +} + +/* + When the bot gets added into the game. +*/ +added() +{ + self endon( "disconnect" ); + + self set_diff(); +} + +/* + When the bot connects to the game. +*/ +connected() +{ + self endon( "disconnect" ); + + self thread difficulty(); + self thread onBotSpawned(); + self thread onSpawned(); + + self thread maps\bots\objectives\_manager::connected(); +} + +/* + The callback for when the bot gets damaged. +*/ +onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime ) +{ + if ( !isdefined( self ) || !isdefined( self.team ) ) + return; + + if ( !isalive( self ) ) + return; + + if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" ) + return; + + if ( iDamage <= 0 ) + return; + + if ( !isdefined( eAttacker ) || !isdefined( eAttacker.team ) ) + return; + + if ( eAttacker == self ) + return; + + if ( !isalive( eAttacker ) ) + return; + + self SetAttacker( eAttacker ); +} + +/* + Updates the bot's difficulty variables. +*/ +difficulty() +{ + self endon( "disconnect" ); + + for ( ;; ) + { + if ( getdvarint( "bots_skill" ) != 9 ) + { + switch ( self.pers["bots"]["skill"]["base"] ) + { + case 1: + self.pers["bots"]["skill"]["aim_time"] = 0.6; + self.pers["bots"]["skill"]["init_react_time"] = 1500; + self.pers["bots"]["skill"]["reaction_time"] = 1000; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 500; + self.pers["bots"]["skill"]["no_trace_look_time"] = 600; + self.pers["bots"]["skill"]["remember_time"] = 750; + self.pers["bots"]["skill"]["fov"] = 0.7; + self.pers["bots"]["skill"]["dist_max"] = 2500; + self.pers["bots"]["skill"]["dist_start"] = 1000; + self.pers["bots"]["skill"]["spawn_time"] = 0.75; + self.pers["bots"]["skill"]["help_dist"] = 0; + self.pers["bots"]["skill"]["semi_time"] = 0.9; + self.pers["bots"]["skill"]["shoot_after_time"] = 1; + self.pers["bots"]["skill"]["aim_offset_time"] = 1.5; + self.pers["bots"]["skill"]["aim_offset_amount"] = 4; + self.pers["bots"]["skill"]["bone_update_interval"] = 2; + self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 0; + self.pers["bots"]["behavior"]["nade"] = 10; + self.pers["bots"]["behavior"]["sprint"] = 30; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 20; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 0; + break; + + case 2: + self.pers["bots"]["skill"]["aim_time"] = 0.55; + self.pers["bots"]["skill"]["init_react_time"] = 1000; + self.pers["bots"]["skill"]["reaction_time"] = 800; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; + self.pers["bots"]["skill"]["no_trace_look_time"] = 1250; + self.pers["bots"]["skill"]["remember_time"] = 1500; + self.pers["bots"]["skill"]["fov"] = 0.65; + self.pers["bots"]["skill"]["dist_max"] = 3000; + self.pers["bots"]["skill"]["dist_start"] = 1500; + self.pers["bots"]["skill"]["spawn_time"] = 0.65; + self.pers["bots"]["skill"]["help_dist"] = 500; + self.pers["bots"]["skill"]["semi_time"] = 0.75; + self.pers["bots"]["skill"]["shoot_after_time"] = 0.75; + self.pers["bots"]["skill"]["aim_offset_time"] = 1; + self.pers["bots"]["skill"]["aim_offset_amount"] = 3; + self.pers["bots"]["skill"]["bone_update_interval"] = 1.5; + self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_ankle_le,j_ankle_ri,j_head"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 10; + self.pers["bots"]["behavior"]["nade"] = 15; + self.pers["bots"]["behavior"]["sprint"] = 45; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 15; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 10; + break; + + case 3: + self.pers["bots"]["skill"]["aim_time"] = 0.4; + self.pers["bots"]["skill"]["init_react_time"] = 750; + self.pers["bots"]["skill"]["reaction_time"] = 500; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; + self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; + self.pers["bots"]["skill"]["remember_time"] = 2000; + self.pers["bots"]["skill"]["fov"] = 0.6; + self.pers["bots"]["skill"]["dist_max"] = 4000; + self.pers["bots"]["skill"]["dist_start"] = 2250; + self.pers["bots"]["skill"]["spawn_time"] = 0.5; + self.pers["bots"]["skill"]["help_dist"] = 750; + self.pers["bots"]["skill"]["semi_time"] = 0.65; + self.pers["bots"]["skill"]["shoot_after_time"] = 0.65; + self.pers["bots"]["skill"]["aim_offset_time"] = 0.75; + self.pers["bots"]["skill"]["aim_offset_amount"] = 2.5; + self.pers["bots"]["skill"]["bone_update_interval"] = 1; + self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 20; + self.pers["bots"]["behavior"]["nade"] = 20; + self.pers["bots"]["behavior"]["sprint"] = 50; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 10; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 25; + break; + + case 4: + self.pers["bots"]["skill"]["aim_time"] = 0.3; + self.pers["bots"]["skill"]["init_react_time"] = 600; + self.pers["bots"]["skill"]["reaction_time"] = 400; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 1000; + self.pers["bots"]["skill"]["no_trace_look_time"] = 1500; + self.pers["bots"]["skill"]["remember_time"] = 3000; + self.pers["bots"]["skill"]["fov"] = 0.55; + self.pers["bots"]["skill"]["dist_max"] = 5000; + self.pers["bots"]["skill"]["dist_start"] = 3350; + self.pers["bots"]["skill"]["spawn_time"] = 0.35; + self.pers["bots"]["skill"]["help_dist"] = 1000; + self.pers["bots"]["skill"]["semi_time"] = 0.5; + self.pers["bots"]["skill"]["shoot_after_time"] = 0.5; + self.pers["bots"]["skill"]["aim_offset_time"] = 0.5; + self.pers["bots"]["skill"]["aim_offset_amount"] = 2; + self.pers["bots"]["skill"]["bone_update_interval"] = 0.75; + self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_spineupper,j_ankle_le,j_ankle_ri,j_head,j_head"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 30; + self.pers["bots"]["behavior"]["nade"] = 25; + self.pers["bots"]["behavior"]["sprint"] = 55; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 10; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 35; + break; + + case 5: + self.pers["bots"]["skill"]["aim_time"] = 0.25; + self.pers["bots"]["skill"]["init_react_time"] = 500; + self.pers["bots"]["skill"]["reaction_time"] = 300; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 1500; + self.pers["bots"]["skill"]["no_trace_look_time"] = 2000; + self.pers["bots"]["skill"]["remember_time"] = 4000; + self.pers["bots"]["skill"]["fov"] = 0.5; + self.pers["bots"]["skill"]["dist_max"] = 7500; + self.pers["bots"]["skill"]["dist_start"] = 5000; + self.pers["bots"]["skill"]["spawn_time"] = 0.25; + self.pers["bots"]["skill"]["help_dist"] = 1500; + self.pers["bots"]["skill"]["semi_time"] = 0.4; + self.pers["bots"]["skill"]["shoot_after_time"] = 0.35; + self.pers["bots"]["skill"]["aim_offset_time"] = 0.35; + self.pers["bots"]["skill"]["aim_offset_amount"] = 1.5; + self.pers["bots"]["skill"]["bone_update_interval"] = 0.5; + self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 40; + self.pers["bots"]["behavior"]["nade"] = 35; + self.pers["bots"]["behavior"]["sprint"] = 60; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 10; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 50; + break; + + case 6: + self.pers["bots"]["skill"]["aim_time"] = 0.2; + self.pers["bots"]["skill"]["init_react_time"] = 250; + self.pers["bots"]["skill"]["reaction_time"] = 150; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 2000; + self.pers["bots"]["skill"]["no_trace_look_time"] = 3000; + self.pers["bots"]["skill"]["remember_time"] = 5000; + self.pers["bots"]["skill"]["fov"] = 0.45; + self.pers["bots"]["skill"]["dist_max"] = 10000; + self.pers["bots"]["skill"]["dist_start"] = 7500; + self.pers["bots"]["skill"]["spawn_time"] = 0.2; + self.pers["bots"]["skill"]["help_dist"] = 2000; + self.pers["bots"]["skill"]["semi_time"] = 0.25; + self.pers["bots"]["skill"]["shoot_after_time"] = 0.25; + self.pers["bots"]["skill"]["aim_offset_time"] = 0.25; + self.pers["bots"]["skill"]["aim_offset_amount"] = 1; + self.pers["bots"]["skill"]["bone_update_interval"] = 0.25; + self.pers["bots"]["skill"]["bones"] = "j_spineupper,j_head,j_head"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 50; + self.pers["bots"]["behavior"]["nade"] = 45; + self.pers["bots"]["behavior"]["sprint"] = 65; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 10; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 75; + break; + + case 7: + self.pers["bots"]["skill"]["aim_time"] = 0.1; + self.pers["bots"]["skill"]["init_react_time"] = 100; + self.pers["bots"]["skill"]["reaction_time"] = 50; + self.pers["bots"]["skill"]["no_trace_ads_time"] = 2500; + self.pers["bots"]["skill"]["no_trace_look_time"] = 4000; + self.pers["bots"]["skill"]["remember_time"] = 7500; + self.pers["bots"]["skill"]["fov"] = 0.4; + self.pers["bots"]["skill"]["dist_max"] = 15000; + self.pers["bots"]["skill"]["dist_start"] = 10000; + self.pers["bots"]["skill"]["spawn_time"] = 0.05; + self.pers["bots"]["skill"]["help_dist"] = 3000; + self.pers["bots"]["skill"]["semi_time"] = 0.1; + self.pers["bots"]["skill"]["shoot_after_time"] = 0; + self.pers["bots"]["skill"]["aim_offset_time"] = 0; + self.pers["bots"]["skill"]["aim_offset_amount"] = 0; + self.pers["bots"]["skill"]["bone_update_interval"] = 0.05; + self.pers["bots"]["skill"]["bones"] = "j_head"; + self.pers["bots"]["skill"]["ads_fov_multi"] = 0.5; + self.pers["bots"]["skill"]["ads_aimspeed_multi"] = 0.5; + + self.pers["bots"]["behavior"]["strafe"] = 65; + self.pers["bots"]["behavior"]["nade"] = 65; + self.pers["bots"]["behavior"]["sprint"] = 70; + self.pers["bots"]["behavior"]["camp"] = 5; + self.pers["bots"]["behavior"]["follow"] = 5; + self.pers["bots"]["behavior"]["crouch"] = 5; + self.pers["bots"]["behavior"]["switch"] = 2; + self.pers["bots"]["behavior"]["jump"] = 90; + break; + } + } + + wait 5; + } +} + +/* + Sets the bot difficulty. +*/ +set_diff() +{ + rankVar = getdvarint( "bots_skill" ); + + switch ( rankVar ) + { + case 0: + self.pers["bots"]["skill"]["base"] = Round( random_normal_distribution( 3.5, 1.75, 1, 7 ) ); + break; + + case 8: + break; + + case 9: + self.pers["bots"]["skill"]["base"] = randomintrange( 1, 7 ); + self.pers["bots"]["skill"]["aim_time"] = 0.05 * randomintrange( 1, 20 ); + self.pers["bots"]["skill"]["init_react_time"] = 50 * randomint( 100 ); + self.pers["bots"]["skill"]["reaction_time"] = 50 * randomint( 100 ); + self.pers["bots"]["skill"]["no_trace_ads_time"] = 50 * randomint( 100 ); + self.pers["bots"]["skill"]["no_trace_look_time"] = 50 * randomint( 100 ); + self.pers["bots"]["skill"]["remember_time"] = 50 * randomint( 100 ); + self.pers["bots"]["skill"]["fov"] = randomfloatrange( -1, 1 ); + + randomNum = randomintrange( 500, 25000 ); + self.pers["bots"]["skill"]["dist_start"] = randomNum; + self.pers["bots"]["skill"]["dist_max"] = randomNum * 2; + + self.pers["bots"]["skill"]["spawn_time"] = 0.05 * randomint( 20 ); + self.pers["bots"]["skill"]["help_dist"] = randomintrange( 500, 25000 ); + self.pers["bots"]["skill"]["semi_time"] = randomfloatrange( 0.05, 1 ); + self.pers["bots"]["skill"]["shoot_after_time"] = randomfloatrange( 0.05, 1 ); + self.pers["bots"]["skill"]["aim_offset_time"] = randomfloatrange( 0.05, 1 ); + self.pers["bots"]["skill"]["aim_offset_amount"] = randomfloatrange( 0.05, 1 ); + self.pers["bots"]["skill"]["bone_update_interval"] = randomfloatrange( 0.05, 1 ); + self.pers["bots"]["skill"]["bones"] = "j_head,j_spineupper,j_ankle_ri,j_ankle_le"; + + self.pers["bots"]["behavior"]["strafe"] = randomint( 100 ); + self.pers["bots"]["behavior"]["nade"] = randomint( 100 ); + self.pers["bots"]["behavior"]["sprint"] = randomint( 100 ); + self.pers["bots"]["behavior"]["camp"] = randomint( 100 ); + self.pers["bots"]["behavior"]["follow"] = randomint( 100 ); + self.pers["bots"]["behavior"]["crouch"] = randomint( 100 ); + self.pers["bots"]["behavior"]["switch"] = randomint( 100 ); + self.pers["bots"]["behavior"]["jump"] = randomint( 100 ); + break; + + default: + self.pers["bots"]["skill"]["base"] = rankVar; + break; + } +} + +/* + When the bot spawned, after the difficulty wait. Start the logic for the bot. +*/ +onBotSpawned() +{ + self endon( "disconnect" ); + level endon( "intermission" ); + + for ( ;; ) + { + self waittill( "bot_spawned" ); + + self thread start_bot_threads(); + } +} + +/* + When the bot spawns. +*/ +onSpawned() +{ + self endon( "disconnect" ); + + for ( ;; ) + { + self waittill( "spawned_player" ); + + self thread maps\bots\objectives\_manager::spawned(); + } +} + +/* + Starts all the bot thinking +*/ +start_bot_threads() +{ + self endon( "disconnect" ); + level endon( "intermission" ); + self endon( "zombified" ); + + self thread doReloadCancel(); + + self thread maps\bots\objectives\_manager::start_bot_threads(); +} + +/* + Changes to the weap +*/ +changeToWeapon( weap ) +{ + self endon( "disconnect" ); + self endon( "zombified" ); + level endon( "game_ended" ); + + if ( !self hasweapon( weap ) ) + return false; + + self switchtoweapon( weap ); + + if ( self getcurrentweapon() == weap ) + return true; + + self waittill_any_timeout( 5, "weapon_change" ); + + return ( self getcurrentweapon() == weap ); +} + +/* + Reload cancels +*/ +doReloadCancel_loop() +{ + ret = self waittill_any_return( "reload", "weapon_change" ); + + if ( self BotIsFrozen() ) + return; + + if ( self usebuttonpressed() ) + return; + + if ( self inLastStand() ) + return; + + curWeap = self getcurrentweapon(); + + if ( !self isWeaponPrimary( curWeap ) ) + return; + + if ( ret == "reload" ) + { + // check single reloads + if ( self getweaponammoclip( curWeap ) < weaponclipsize( curWeap ) ) + return; + } + + // check difficulty + if ( self.pers["bots"]["skill"]["base"] <= 3 ) + return; + + // check if got another weapon + weaponslist = self getweaponslistprimaries(); + weap = ""; + + while ( weaponslist.size ) + { + weapon = weaponslist[randomint( weaponslist.size )]; + weaponslist = array_remove( weaponslist, weapon ); + + if ( !self isWeaponPrimary( weapon ) ) + continue; + + if ( curWeap == weapon || weapon == "none" || weapon == "" ) + continue; + + weap = weapon; + break; + } + + if ( weap == "" ) + return; + + // do the cancel + wait 0.1; + self thread changeToWeapon( weap ); + wait 0.25; + self thread changeToWeapon( curWeap ); + wait 2; +} + +/* + Reload cancels +*/ +doReloadCancel() +{ + self endon( "disconnect" ); + self endon( "zombified" ); + + for ( ;; ) + { + self doReloadCancel_loop(); + } +} diff --git a/maps/bots/_bot_utility.gsc b/maps/bots/_bot_utility.gsc index 329d3b5..db6fd62 100644 --- a/maps/bots/_bot_utility.gsc +++ b/maps/bots/_bot_utility.gsc @@ -8,7 +8,7 @@ wait_for_builtins() { for ( i = 0; i < 20; i++ ) { - if ( isDefined( level.bot_builtins ) ) + if ( isdefined( level.bot_builtins ) ) return true; if ( i < 18 ) @@ -25,7 +25,7 @@ wait_for_builtins() */ BotBuiltinPrintConsole( s ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["printconsole"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["printconsole"] ) ) { [[ level.bot_builtins["printconsole" ]]]( s ); } @@ -33,11 +33,11 @@ BotBuiltinPrintConsole( s ) /* Bot action, does a bot action - botAction() + botaction() */ BotBuiltinBotAction( action ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botaction"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["botaction"] ) ) { self [[ level.bot_builtins["botaction" ]]]( action ); } @@ -45,11 +45,11 @@ BotBuiltinBotAction( action ) /* Clears the bot from movement and actions - botStop() + botstop() */ BotBuiltinBotStop() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botstop"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["botstop"] ) ) { self [[ level.bot_builtins["botstop" ]]](); } @@ -57,11 +57,11 @@ BotBuiltinBotStop() /* Sets the bot's movement - botMovement(, ) + botmovement(, ) */ BotBuiltinBotMovement( left, forward ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botmovement"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["botmovement"] ) ) { self [[ level.bot_builtins["botmovement" ]]]( left, forward ); } @@ -72,7 +72,7 @@ BotBuiltinBotMovement( left, forward ) */ BotBuiltinBotMeleeParams( yaw, dist ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["botmeleeparams"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["botmeleeparams"] ) ) { self [[ level.bot_builtins["botmeleeparams" ]]]( yaw, dist ); } @@ -84,7 +84,7 @@ BotBuiltinBotMeleeParams( yaw, dist ) */ BotBuiltinIsBot() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["isbot"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["isbot"] ) ) { return self [[ level.bot_builtins["isbot" ]]](); } @@ -97,7 +97,7 @@ BotBuiltinIsBot() */ BotBuiltinGeneratePath( from, to, team, best_effort ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["generatepath"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["generatepath"] ) ) { return [[ level.bot_builtins["generatepath" ]]]( from, to, team, best_effort ); } @@ -110,7 +110,7 @@ BotBuiltinGeneratePath( from, to, team, best_effort ) */ BotBuiltinGetFunction( file, threadname ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["getfunction"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["getfunction"] ) ) { return [[ level.bot_builtins["getfunction" ]]]( file, threadname ); } @@ -123,7 +123,7 @@ BotBuiltinGetFunction( file, threadname ) */ BotBuiltinGetMins() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["getmins"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["getmins"] ) ) { return self [[ level.bot_builtins["getmins" ]]](); } @@ -136,7 +136,7 @@ BotBuiltinGetMins() */ BotBuiltinGetMaxs() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["getmaxs"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["getmaxs"] ) ) { return self [[ level.bot_builtins["getmaxs" ]]](); } @@ -149,7 +149,7 @@ BotBuiltinGetMaxs() */ BotBuiltinGetGuid() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["getguid"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["getguid"] ) ) { return self [[ level.bot_builtins["getguid" ]]](); } @@ -161,7 +161,7 @@ BotBuiltinGetGuid() */ BotBuiltinSetAllowedTraversals( bot_allowed_negotiation_links ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["setallowedtraversals"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["setallowedtraversals"] ) ) { [[ level.bot_builtins["setallowedtraversals" ]]]( bot_allowed_negotiation_links ); } @@ -171,7 +171,7 @@ BotBuiltinSetAllowedTraversals( bot_allowed_negotiation_links ) */ BotBuiltinSetIgnoredLinks( bot_ignore_links ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["setignoredlinks"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["setignoredlinks"] ) ) { [[ level.bot_builtins["setignoredlinks" ]]]( bot_ignore_links ); } @@ -181,7 +181,7 @@ BotBuiltinSetIgnoredLinks( bot_ignore_links ) */ BotBuiltinGetNodeNumber() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["getnodenumber"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["getnodenumber"] ) ) { return self [[ level.bot_builtins["getnodenumber" ]]](); } @@ -193,7 +193,7 @@ BotBuiltinGetNodeNumber() */ BotBuiltinGetLinkedNodes() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["getlinkednodes"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["getlinkednodes"] ) ) { return self [[ level.bot_builtins["getlinkednodes" ]]](); } @@ -205,7 +205,7 @@ BotBuiltinGetLinkedNodes() */ BotBuiltinAddTestClient() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["addtestclient"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["addtestclient"] ) ) { return [[ level.bot_builtins["addtestclient" ]]](); } @@ -217,7 +217,7 @@ BotBuiltinAddTestClient() */ BotBuiltinCmdExec( what ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["cmdexec"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["cmdexec"] ) ) { [[ level.bot_builtins["cmdexec" ]]]( what ); } @@ -227,7 +227,7 @@ BotBuiltinCmdExec( what ) */ BotBuiltinNotifyOnPlayerCommand( cmd, notif ) { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["notifyonplayercommand"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["notifyonplayercommand"] ) ) { self [[ level.bot_builtins["notifyonplayercommand" ]]]( cmd, notif ); } @@ -238,7 +238,7 @@ BotBuiltinNotifyOnPlayerCommand( cmd, notif ) */ BotBuiltinIsHost() { - if ( isDefined( level.bot_builtins ) && isDefined( level.bot_builtins["ishost"] ) ) + if ( isdefined( level.bot_builtins ) && isdefined( level.bot_builtins["ishost"] ) ) { return self [[ level.bot_builtins["ishost" ]]](); } @@ -251,7 +251,7 @@ BotBuiltinIsHost() */ is_host() { - return ( isDefined( self.pers["bot_host"] ) && self.pers["bot_host"] ); + return ( isdefined( self.pers["bot_host"] ) && self.pers["bot_host"] ); } /* @@ -266,20 +266,20 @@ doHostCheck() result = false; - if ( getDvar( "bots_main_firstIsHost" ) != "0" ) + if ( getdvar( "bots_main_firstIsHost" ) != "0" ) { BotBuiltinPrintConsole( "WARNING: bots_main_firstIsHost is enabled" ); - if ( getDvar( "bots_main_firstIsHost" ) == "1" ) + if ( getdvar( "bots_main_firstIsHost" ) == "1" ) { - setDvar( "bots_main_firstIsHost", self BotBuiltinGetGuid() ); + setdvar( "bots_main_firstIsHost", self BotBuiltinGetGuid() ); } - if ( getDvar( "bots_main_firstIsHost" ) == self BotBuiltinGetGuid() + "" ) + if ( getdvar( "bots_main_firstIsHost" ) == self BotBuiltinGetGuid() + "" ) result = true; } - DvarGUID = getDvar( "bots_main_GUIDs" ); + DvarGUID = getdvar( "bots_main_GUIDs" ); if ( DvarGUID != "" ) { @@ -388,7 +388,7 @@ BotGetRandom() */ BotGetTargetRandom() { - if ( !isDefined( self.bot.target ) ) + if ( !isdefined( self.bot.target ) ) return undefined; return self.bot.target.rand; @@ -486,7 +486,7 @@ BotHasObjective() */ HasScriptGoal() { - return ( isDefined( self GetScriptGoal() ) ); + return ( isdefined( self GetScriptGoal() ) ); } /* @@ -502,7 +502,7 @@ GetScriptGoal() */ SetScriptGoal( goal, dist ) { - if ( !isDefined( dist ) ) + if ( !isdefined( dist ) ) dist = 16; self.bot.script_goal = goal; @@ -575,7 +575,7 @@ GetScriptAimPos() */ HasScriptAimPos() { - return isDefined( self GetScriptAimPos() ); + return isdefined( self GetScriptAimPos() ); } /* @@ -619,7 +619,7 @@ GetThreat() */ HasScriptEnemy() { - return ( isDefined( self.bot.script_target ) ); + return ( isdefined( self.bot.script_target ) ); } /* @@ -627,7 +627,7 @@ HasScriptEnemy() */ HasThreat() { - return ( isDefined( self GetThreat() ) ); + return ( isdefined( self GetThreat() ) ); } /* @@ -641,10 +641,10 @@ getValidTube() { weap = weaps[i]; - if ( !self getAmmoCount( weap ) ) + if ( !self getammocount( weap ) ) continue; - if ( isSubStr( weap, "gl_" ) && !isSubStr( weap, "_gl_" ) ) + if ( issubstr( weap, "gl_" ) && !issubstr( weap, "_gl_" ) ) return weap; } @@ -663,10 +663,10 @@ getValidGrenade() for ( i = 0; i < grenadeTypes.size; i++ ) { - if ( !self hasWeapon( grenadeTypes[i] ) ) + if ( !self hasweapon( grenadeTypes[i] ) ) continue; - if ( !self getAmmoCount( grenadeTypes[i] ) ) + if ( !self getammocount( grenadeTypes[i] ) ) continue; possibles[possibles.size] = grenadeTypes[i]; @@ -683,7 +683,7 @@ PickRandom( arr ) if ( !arr.size ) return undefined; - return arr[randomInt( arr.size )]; + return arr[randomint( arr.size )]; } /* @@ -709,7 +709,7 @@ WeaponIsFullAuto( weap ) { weaptoks = strtok( weap, "_" ); - return isDefined( weaptoks[0] ) && isString( weaptoks[0] ) && isdefined( level.bots_fullautoguns[weaptoks[0]] ); + return isdefined( weaptoks[0] ) && isstring( weaptoks[0] ) && isdefined( level.bots_fullautoguns[weaptoks[0]] ); } /* @@ -727,7 +727,7 @@ waittill_either_return_( str1, str2 ) */ waittill_either_return( str1, str2 ) { - if ( !isDefined( self waittill_either_return_( str1, str2 ) ) ) + if ( !isdefined( self waittill_either_return_( str1, str2 ) ) ) return str1; return str2; @@ -805,34 +805,34 @@ bot_wait_for_host() { host = undefined; - while ( !isDefined( level ) || !isDefined( level.players ) ) + while ( !isdefined( level ) || !isdefined( level.players ) ) wait 0.05; - for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) + for ( i = getdvarfloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { host = GetHostPlayer(); - if ( isDefined( host ) ) + if ( isdefined( host ) ) break; wait 0.05; } - if ( !isDefined( host ) ) + if ( !isdefined( host ) ) return; - for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) + for ( i = getdvarfloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { - if ( IsDefined( host.pers[ "team" ] ) ) + if ( isdefined( host.pers[ "team" ] ) ) break; wait 0.05; } - if ( !IsDefined( host.pers[ "team" ] ) ) + if ( !isdefined( host.pers[ "team" ] ) ) return; - for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) + for ( i = getdvarfloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { if ( host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis" ) break; @@ -846,26 +846,26 @@ bot_wait_for_host() */ getConeDot( to, from, dir ) { - dirToTarget = VectorNormalize( to - from ); - forward = AnglesToForward( dir ); + dirToTarget = vectornormalize( to - from ); + forward = anglestoforward( dir ); return vectordot( dirToTarget, forward ); } /* Returns the distance squared in a 2d space */ -DistanceSquared2D( to, from ) +distancesquared2D( to, from ) { to = ( to[0], to[1], 0 ); from = ( from[0], from[1], 0 ); - return DistanceSquared( to, from ); + return distancesquared( to, from ); } /* - Distance from box + distance from box */ -RectDistanceSquared( origin ) +Rectdistancesquared( origin ) { dx = 0; dy = 0; @@ -936,7 +936,7 @@ float( num ) { setdvar( "temp_dvar_bot_util", num ); - return GetDvarFloat( "temp_dvar_bot_util" ); + return getdvarfloat( "temp_dvar_bot_util" ); } /* @@ -944,7 +944,7 @@ float( num ) */ get_nodes_in_playable_area() { - total_nodes = getAllNodes(); + total_nodes = getallnodes(); filtered_nodes = []; for ( i = 0; i < total_nodes.size; i++ ) @@ -974,7 +974,7 @@ is_point_in_playable_area( point ) in_playable_area = false; - if ( !isDefined( playable_area ) || playable_area.size < 1 ) + if ( !isdefined( playable_area ) || playable_area.size < 1 ) { in_playable_area = true; } @@ -985,7 +985,7 @@ is_point_in_playable_area( point ) { for ( p = 0; p < playable_area.size; p++ ) { - if ( temp_ent isTouching( playable_area[ p ] ) ) + if ( temp_ent istouching( playable_area[ p ] ) ) { in_playable_area = true; break; @@ -1145,11 +1145,11 @@ load_waypoints() BotBuiltinSetIgnoredLinks( bot_ignore_links ); level.bot_ignore_links = bot_ignore_links; - level.waypoints = GetAllNodes(); - level.waypointCount = level.waypoints.size; + level.waypoints = getallnodes(); + level.waypointcount = level.waypoints.size; - level.waypointsInPlayableArea = []; - level.waypointsInPlayableArea = get_nodes_in_playable_area(); + level.waypointsinplayablearea = []; + level.waypointsinplayablearea = get_nodes_in_playable_area(); } /* @@ -1175,7 +1175,7 @@ getBotToKick() { bots = getBotArray(); - if ( !isDefined( bots ) || !isDefined( bots.size ) || bots.size <= 0 || !isDefined( bots[0] ) ) + if ( !isdefined( bots ) || !isdefined( bots.size ) || bots.size <= 0 || !isdefined( bots[0] ) ) return undefined; tokick = undefined; @@ -1185,13 +1185,13 @@ getBotToKick() { bot = bots[i]; - if ( !isDefined( bot ) ) + if ( !isdefined( bot ) ) continue; - if ( !isDefined( bot.pers ) || !isDefined( bot.pers["bots"] ) || !isDefined( bot.pers["bots"]["skill"] ) || !isDefined( bot.pers["bots"]["skill"]["base"] ) ) + if ( !isdefined( bot.pers ) || !isdefined( bot.pers["bots"] ) || !isdefined( bot.pers["bots"]["skill"] ) || !isdefined( bot.pers["bots"]["skill"]["base"] ) ) continue; - if ( isDefined( tokick ) && bot.pers["bots"]["skill"]["base"] > tokick.pers["bots"]["skill"]["base"] ) + if ( isdefined( tokick ) && bot.pers["bots"]["skill"]["base"] > tokick.pers["bots"]["skill"]["base"] ) continue; tokick = bot; @@ -1239,7 +1239,7 @@ ReverseHeap( item, item2 ) HeapPriority( item, item2 ) { - return item.fPriority > item2.fPriority; + return item.fpriority > item2.fpriority; } /* @@ -1255,7 +1255,7 @@ HeapTraceFraction( item, item2 ) */ NewHeap( compare ) { - heap_node = spawnStruct(); + heap_node = spawnstruct(); heap_node.data = []; heap_node.compare = compare; @@ -1346,15 +1346,6 @@ HeapRemove() */ Log( x ) { - /* if (!isDefined(level.log_cache)) - level.log_cache = []; - - key = x + ""; - - if (isDefined(level.log_cache[key])) - return level.log_cache[key];*/ - - //thanks Bob__ at stackoverflow old_sum = 0.0; xmlxpl = ( x - 1 ) / ( x + 1 ); xmlxpl_2 = xmlxpl * xmlxpl; @@ -1371,8 +1362,6 @@ Log( x ) } answer = 2.0 * sum; - - //level.log_cache[key] = answer; return answer; } @@ -1414,7 +1403,7 @@ array_std_deviation( array, mean ) total = total + tmp[i]; } - return Sqrt( total / array.size ); + return sqrt( total / array.size ); } /* @@ -1430,21 +1419,21 @@ random_normal_distribution( mean, std_deviation, lower_bound, upper_bound ) while ( w >= 1 ) { - x1 = 2 * RandomFloatRange( 0, 1 ) - 1; - x2 = 2 * RandomFloatRange( 0, 1 ) - 1; + x1 = 2 * randomfloatrange( 0, 1 ) - 1; + x2 = 2 * randomfloatrange( 0, 1 ) - 1; w = x1 * x1 + x2 * x2; } - w = Sqrt( ( -2.0 * Log( w ) ) / w ); + w = sqrt( ( -2.0 * Log( w ) ) / w ); y1 = x1 * w; number = mean + y1 * std_deviation; - if ( IsDefined( lower_bound ) && number < lower_bound ) + if ( isdefined( lower_bound ) && number < lower_bound ) { number = lower_bound; } - if ( IsDefined( upper_bound ) && number > upper_bound ) + if ( isdefined( upper_bound ) && number > upper_bound ) { number = upper_bound; } @@ -1477,12 +1466,12 @@ isReviving( revivee ) */ getRandomGoal() { - if ( !level.waypointsInPlayableArea.size ) + if ( !level.waypointsinplayablearea.size ) { return self.origin; } - return PickRandom( level.waypointsInPlayableArea ).origin; + return PickRandom( level.waypointsinplayablearea ).origin; } /* @@ -1490,7 +1479,7 @@ getRandomGoal() */ targetIsDog() { - return isDefined( self.targetname ) && self.targetname == "zombie_dog"; + return isdefined( self.targetname ) && self.targetname == "zombie_dog"; } /* @@ -1498,7 +1487,7 @@ targetIsDog() */ targetIsGibbed() { - return isDefined( self.gibbed ) && self.gibbed; + return isdefined( self.gibbed ) && self.gibbed; } /* @@ -1506,7 +1495,7 @@ targetIsGibbed() */ isWeaponPrimary( weap ) { - weaps = self GetWeaponsListPrimaries(); + weaps = self getweaponslistprimaries(); for ( i = 0; i < weaps.size; i++ ) { @@ -1523,7 +1512,7 @@ isWeaponPrimary( weap ) GetPathIsInaccessible( from, to, team, best_effort ) { path = BotBuiltinGeneratePath( from, to, team, best_effort ); - return ( !isDefined( path ) || ( path.size <= 0 ) ); + return ( !isdefined( path ) || ( path.size <= 0 ) ); } /* @@ -1533,7 +1522,7 @@ get_path_dist( start, end, team ) { path = BotBuiltinGeneratePath( start, end, team, 192.0 ); - if ( !isDefined( path ) || path.size <= 0 ) + if ( !isdefined( path ) || path.size <= 0 ) { return 999999999; } @@ -1585,27 +1574,27 @@ ClampLerp( dist, min_dist, max_dist, max_bonus, min_bonus ) */ get_angle_offset_node( forward_size, angle_offset, offset ) { - if ( !isDefined( forward_size ) ) + if ( !isdefined( forward_size ) ) { forward_size = 40; } - if ( !isDefined( angle_offset ) ) + if ( !isdefined( angle_offset ) ) { angle_offset = ( 0, 0, 0 ); } - if ( !isDefined( offset ) ) + if ( !isdefined( offset ) ) { offset = ( 0, 0, 0 ); } angles = ( 0, self.angles[ 1 ], 0 ); angles += angle_offset; - node = self.origin + ( AnglesToForward( angles ) * forward_size ) + offset; + node = self.origin + ( anglestoforward( angles ) * forward_size ) + offset; node = clamp_to_ground( node ); - if ( getDvarInt( "bots_main_debug" ) ) + if ( getdvarint( "bots_main_debug" ) ) { self thread debug_offset_line( node ); } @@ -1622,7 +1611,7 @@ debug_offset_line( node ) self notify( "debug_offset_line" ); self endon( "debug_offset_line" ); - while ( isDefined( self ) ) + while ( isdefined( self ) ) { line( self.origin, node ); wait 0.05; @@ -1634,7 +1623,7 @@ debug_offset_line( node ) */ PointInsideUseTrigger( point ) { - if ( getDvarInt( "bots_main_debug" ) ) + if ( getdvarint( "bots_main_debug" ) ) { self thread debug_bounding_box_for_ent(); } @@ -1650,12 +1639,12 @@ PointInsideUseTrigger( point ) box.z0 = self.origin[2] + mins[2]; box.z1 = self.origin[2] + maxs[2]; - if ( box RectDistanceSquared( self.origin ) > 72 * 72 ) + if ( box Rectdistancesquared( self.origin ) > 72 * 72 ) { return false; } - if ( !sightTracePassed( point, self.origin, false, undefined ) ) + if ( !sighttracepassed( point, self.origin, false, undefined ) ) { return false; } @@ -1672,10 +1661,10 @@ debug_bounding_box_for_ent( color ) self notify( "debug_bounding_box_for_ent" ); self endon( "debug_bounding_box_for_ent" ); - if ( !isDefined( color ) ) - color = ( randomFloatRange( 0, 1 ), randomFloatRange( 0, 1 ), randomFloatRange( 0, 1 ) ); + if ( !isdefined( color ) ) + color = ( randomfloatrange( 0, 1 ), randomfloatrange( 0, 1 ), randomfloatrange( 0, 1 ) ); - while ( isDefined( self ) ) + while ( isdefined( self ) ) { mins = self BotBuiltinGetMins(); maxs = self BotBuiltinGetMaxs(); @@ -1706,6 +1695,6 @@ debug_bounding_box_for_ent( color ) */ clamp_to_ground( org ) { - trace = playerPhysicsTrace( org + ( 0, 0, 20 ), org - ( 0, 0, 2000 ) ); + trace = playerphysicstrace( org + ( 0, 0, 20 ), org - ( 0, 0, 2000 ) ); return trace; } diff --git a/maps/bots/objectives/_manager.gsc b/maps/bots/objectives/_manager.gsc index 59902c0..1ec8cf7 100644 --- a/maps/bots/objectives/_manager.gsc +++ b/maps/bots/objectives/_manager.gsc @@ -39,9 +39,9 @@ watch_for_objective_canceled() obj_name = "undefined"; - if ( isDefined( self.bot_current_objective ) ) + if ( isdefined( self.bot_current_objective ) ) { - obj_name = self.bot_current_objective.sName; + obj_name = self.bot_current_objective.sname; } self BotNotifyBotEvent( "debug", "watch_for_objective_canceled: " + obj_name + ": " + reason ); @@ -60,11 +60,11 @@ clean_objective_on_completion() obj_name = "undefined"; - if ( isDefined( self.bot_current_objective ) ) + if ( isdefined( self.bot_current_objective ) ) { - obj_name = self.bot_current_objective.sName; + obj_name = self.bot_current_objective.sname; - self.bot_current_objective.eParentObj.aBotProcessTimes[self GetEntityNumber() + ""] = getTime(); + self.bot_current_objective.eparentobj.abotprocesstimes[self getentitynumber() + ""] = gettime(); } self BotNotifyBotEvent( "debug", "clean_objective_on_completion: " + obj_name + ": " + successful + ": " + reason ); @@ -95,21 +95,21 @@ bot_objective_think() // find all avail objectives objectives = []; - now = getTime(); - our_key = self GetEntityNumber() + ""; + now = gettime(); + our_key = self getentitynumber() + ""; for ( i = 0; i < level.bot_objectives.size; i++ ) { objective = level.bot_objectives[i]; // check the process rate - if ( isDefined( objective.aBotProcessTimes[our_key] ) && now - objective.aBotProcessTimes[our_key] < objective.iProcessRate ) + if ( isdefined( objective.abotprocesstimes[our_key] ) && now - objective.abotprocesstimes[our_key] < objective.iprocessrate ) { continue; } - objectives = array_merge( objectives, self [[objective.fpFinder]]( objective ) ); - objective.aBotProcessTimes[our_key] = now; + objectives = array_merge( objectives, self [[objective.fpfinder]]( objective ) ); + objective.abotprocesstimes[our_key] = now; } if ( objectives.size <= 0 ) @@ -122,7 +122,7 @@ bot_objective_think() for ( i = 0; i < objectives.size; i++ ) { - if ( objectives[i].fPriority <= -100 ) + if ( objectives[i].fpriority <= -100 ) { continue; } @@ -133,36 +133,36 @@ bot_objective_think() // pop the top! best_prio = heap.data[0]; - if ( !isDefined( best_prio ) ) + if ( !isdefined( best_prio ) ) { continue; } // already on a better obj - if ( isDefined( self.bot_current_objective ) && ( best_prio.GUID == self.bot_current_objective.GUID || best_prio.fPriority < self [[self.bot_current_objective.eParentObj.fpPriorty]]( self.bot_current_objective.eParentObj, self.bot_current_objective.eEnt ) ) ) + if ( isdefined( self.bot_current_objective ) && ( best_prio.guid == self.bot_current_objective.guid || best_prio.fpriority < self [[self.bot_current_objective.eparentobj.fppriorty]]( self.bot_current_objective.eparentobj, self.bot_current_objective.eent ) ) ) { continue; } // DO THE OBJ // cancel the old obj - if ( isDefined( self.bot_current_objective ) ) + if ( isdefined( self.bot_current_objective ) ) { // cancel it - self CancelObjective( "new obj: " + best_prio.sName ); + self CancelObjective( "new obj: " + best_prio.sname ); // wait for it to clean up self waittill( "completed_bot_objective" ); // redo the loop, should do the obj next iteration - best_prio.eParentObj.aBotProcessTimes[our_key] = undefined; + best_prio.eparentobj.abotprocesstimes[our_key] = undefined; continue; } // ready to execute - self BotNotifyBotEvent( "debug", "bot_objective_think: " + best_prio.sName ); + self BotNotifyBotEvent( "debug", "bot_objective_think: " + best_prio.sname ); self.bot_current_objective = best_prio; - self thread [[best_prio.eParentObj.fpExecuter]]( best_prio ); + self thread [[best_prio.eparentobj.fpexecuter]]( best_prio ); } } diff --git a/maps/bots/objectives/_perkmachine.gsc b/maps/bots/objectives/_perkmachine.gsc index 6492641..2528de7 100644 --- a/maps/bots/objectives/_perkmachine.gsc +++ b/maps/bots/objectives/_perkmachine.gsc @@ -5,13 +5,13 @@ init() { - vending_triggers = GetEntArray( "zombie_vending", "targetname" ); + vending_triggers = getentarray( "zombie_vending", "targetname" ); - if ( !isDefined( vending_triggers ) || vending_triggers.size < 1 ) + if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 ) { - vending_triggers = getEntArray( "harrybo21_perk_trigger", "targetname" ); + vending_triggers = getentarray( "harrybo21_perk_trigger", "targetname" ); - if ( !isDefined( vending_triggers ) || vending_triggers.size < 1 ) + if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 ) { return; } @@ -55,13 +55,13 @@ Finder( eObj ) return answer; } - vending_triggers = GetEntArray( "zombie_vending", "targetname" ); + vending_triggers = getentarray( "zombie_vending", "targetname" ); - if ( !isDefined( vending_triggers ) || vending_triggers.size < 1 ) + if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 ) { - vending_triggers = getEntArray( "harrybo21_perk_trigger", "targetname" ); + vending_triggers = getentarray( "harrybo21_perk_trigger", "targetname" ); - if ( !isDefined( vending_triggers ) || vending_triggers.size < 1 ) + if ( !isdefined( vending_triggers ) || vending_triggers.size < 1 ) { return answer; } @@ -85,14 +85,14 @@ Finder( eObj ) } // perk limit?? - if ( self HasPerk( perk ) ) + if ( self hasperk( perk ) ) { continue; } machine = vending getMachine(); - if ( !isDefined( machine ) ) + if ( !isdefined( machine ) ) { continue; } @@ -112,7 +112,7 @@ Finder( eObj ) getMachine() { - return GetEnt( self.target, "targetname" ); + return getent( self.target, "targetname" ); } getVendingPerk() @@ -187,7 +187,7 @@ Executer( eObj ) self endon( "disconnect" ); self endon( "zombified" ); - vending = eObj.eEnt; + vending = eObj.eent; self thread WatchForCancel( vending ); @@ -197,7 +197,7 @@ Executer( eObj ) self ClearScriptAimPos(); self ClearScriptGoal(); - self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); + self CompletedObjective( eObj.bwassuccessful, eObj.sreason ); } WatchForCancelCleanup() @@ -236,7 +236,7 @@ WatchToGoToMachine( vending ) { wait 0.05; - if ( self IsTouching( vending ) || vending PointInsideUseTrigger( self.origin ) ) + if ( self istouching( vending ) || vending PointInsideUseTrigger( self.origin ) ) { self notify( "goal" ); break; // is this needed? @@ -248,7 +248,7 @@ GoDoPerkMachine( eObj ) { self endon( "cancel_bot_objective" ); - vending = eObj.eEnt; + vending = eObj.eent; machine = vending getMachine(); perk = vending getVendingPerk(); org = self getOffset( machine ); @@ -261,13 +261,13 @@ GoDoPerkMachine( eObj ) if ( result != "goal" ) { - eObj.sReason = "didn't go to machine"; + eObj.sreason = "didn't go to machine"; return; } - if ( !self IsTouching( vending ) && !vending PointInsideUseTrigger( self.origin ) ) + if ( !self istouching( vending ) && !vending PointInsideUseTrigger( self.origin ) ) { - eObj.sReason = "not touching machine"; + eObj.sreason = "not touching machine"; return; } @@ -282,6 +282,6 @@ GoDoPerkMachine( eObj ) wait 0.1; // ok we pressed use, DONE - eObj.sReason = "completed " + perk; - eObj.bWasSuccessful = true; + eObj.sreason = "completed " + perk; + eObj.bwassuccessful = true; } diff --git a/maps/bots/objectives/_powerup.gsc b/maps/bots/objectives/_powerup.gsc index 1b94dca..f60e395 100644 --- a/maps/bots/objectives/_powerup.gsc +++ b/maps/bots/objectives/_powerup.gsc @@ -17,7 +17,7 @@ Finder( eObj ) for ( i = 0; i < ents.size; i++ ) { // not a powerup script_model - if ( !isDefined( ents[i].powerup_name ) ) + if ( !isdefined( ents[i].powerup_name ) ) { continue; } @@ -59,7 +59,7 @@ Executer( eObj ) self endon( "disconnect" ); self endon( "zombified" ); - powerup = eObj.eEnt; + powerup = eObj.eent; org = powerup.origin; self thread IncrementBotsForEntity( powerup ); @@ -73,11 +73,11 @@ Executer( eObj ) if ( distance( org, self.origin ) <= 64 ) { - eObj.sReason = "completed"; - eObj.bWasSuccessful = true; + eObj.sreason = "completed"; + eObj.bwassuccessful = true; } - self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); + self CompletedObjective( eObj.bwassuccessful, eObj.sreason ); } WatchForCancelCleanup() @@ -113,7 +113,7 @@ GoDoPowerup( eObj ) { self endon( "cancel_bot_objective" ); - powerup = eObj.eEnt; + powerup = eObj.eent; // go to it self SetScriptGoal( powerup.origin, 32 ); @@ -122,21 +122,21 @@ GoDoPowerup( eObj ) if ( result != "goal" ) { - eObj.sReason = "didn't go to powerup"; + eObj.sreason = "didn't go to powerup"; return; } - if ( !isDefined( powerup ) || !isDefined( powerup.origin ) ) + if ( !isdefined( powerup ) || !isdefined( powerup.origin ) ) { return; } if ( distance( powerup.origin, self.origin ) > 64 ) { - eObj.sReason = "not touching it"; + eObj.sreason = "not touching it"; return; } - eObj.sReason = "completed"; - eObj.bWasSuccessful = true; + eObj.sreason = "completed"; + eObj.bwassuccessful = true; } diff --git a/maps/bots/objectives/_revive.gsc b/maps/bots/objectives/_revive.gsc index a75854c..ad3dab6 100644 --- a/maps/bots/objectives/_revive.gsc +++ b/maps/bots/objectives/_revive.gsc @@ -17,7 +17,7 @@ Finder( eObj ) { Player = Players[i]; - if ( !IsDefined( Player ) || !IsDefined( Player.team ) ) + if ( !isdefined( Player ) || !isdefined( Player.team ) ) { continue; } @@ -71,7 +71,7 @@ Executer( eObj ) self endon( "disconnect" ); self endon( "zombified" ); - revivee = eObj.eEnt; + revivee = eObj.eent; self thread IncrementBotsForEntity( revivee ); self thread WatchForCancelRevive( revivee ); @@ -84,7 +84,7 @@ Executer( eObj ) self ClearScriptGoal(); self ClearPriorityObjective(); - self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); + self CompletedObjective( eObj.bwassuccessful, eObj.sreason ); } WatchForCancelReviveCleanup() @@ -143,7 +143,7 @@ WatchToGoToGuy( revivee ) { wait 1; - if ( self IsTouching( revivee.revivetrigger ) ) + if ( self istouching( revivee.revivetrigger ) ) { self notify( "goal" ); break; // is this needed? @@ -156,14 +156,14 @@ WatchForSuccessRevive( eObj ) self endon( "disconnect" ); self endon( "zombified" ); - revivee = eObj.eEnt; + revivee = eObj.eent; ret = self waittill_either_return( "cancel_bot_objective", "completed_bot_objective" ); - if ( ret == "cancel_bot_objective" && isDefined( revivee ) && !revivee inLastStand() ) + if ( ret == "cancel_bot_objective" && isdefined( revivee ) && !revivee inLastStand() ) { - eObj.bWasSuccessful = true; - eObj.sReason = "revived him!"; + eObj.bwassuccessful = true; + eObj.sreason = "revived him!"; } } @@ -171,7 +171,7 @@ GoDoRevive( eObj ) { self endon( "cancel_bot_objective" ); - revivee = eObj.eEnt; + revivee = eObj.eent; // go to guy self thread WatchToGoToGuy( revivee ); @@ -182,13 +182,13 @@ GoDoRevive( eObj ) if ( result != "goal" ) { - eObj.sReason = "didn't go to guy"; + eObj.sreason = "didn't go to guy"; return; } - if ( !self IsTouching( revivee.revivetrigger ) ) + if ( !self istouching( revivee.revivetrigger ) ) { - eObj.sReason = "not touching guy"; + eObj.sreason = "not touching guy"; return; } @@ -198,12 +198,12 @@ GoDoRevive( eObj ) // now lets hold use until he is up or otherwise self thread WatchForSuccessRevive( eObj ); - while ( self IsTouching( revivee.revivetrigger ) ) + while ( self istouching( revivee.revivetrigger ) ) { self thread BotPressUse( 0.15 ); wait 0.1; } - eObj.sReason = "not touching guy"; + eObj.sreason = "not touching guy"; } diff --git a/maps/bots/objectives/_treasurechest.gsc b/maps/bots/objectives/_treasurechest.gsc index d4405e8..8a51a6e 100644 --- a/maps/bots/objectives/_treasurechest.gsc +++ b/maps/bots/objectives/_treasurechest.gsc @@ -12,17 +12,17 @@ Finder( eObj ) return answer; } - weapons = self GetWeaponsList(); + weapons = self getweaponslist(); // TODO check if need a new weapon, rate weapons too is better then current etc chests = level.chests; - if ( !isDefined( chests ) ) + if ( !isdefined( chests ) ) { - chests = GetEntArray( "treasure_chest_use", "targetname" ); + chests = getentarray( "treasure_chest_use", "targetname" ); } - if ( !isDefined( chests ) || chests.size <= 0 ) + if ( !isdefined( chests ) || chests.size <= 0 ) { return answer; } @@ -32,24 +32,24 @@ Finder( eObj ) chest = chests[i]; // not active chest - if ( isDefined( chest.disabled ) && chest.disabled ) + if ( isdefined( chest.disabled ) && chest.disabled ) { continue; } // box is waiting for someone to grab weapon - if ( isDefined( chest.grab_weapon_hint ) && chest.grab_weapon_hint ) + if ( isdefined( chest.grab_weapon_hint ) && chest.grab_weapon_hint ) { continue; } cost = 950; - if ( IsDefined( level.zombie_treasure_chest_cost ) ) + if ( isdefined( level.zombie_treasure_chest_cost ) ) { cost = level.zombie_treasure_chest_cost; } - else if ( isDefined( chest.zombie_cost ) ) + else if ( isdefined( chest.zombie_cost ) ) { cost = chest.zombie_cost; } @@ -62,7 +62,7 @@ Finder( eObj ) lid = getent( chest.target, "targetname" ); - if ( !isDefined( lid ) ) + if ( !isdefined( lid ) ) { continue; } @@ -112,7 +112,7 @@ Executer( eObj ) self endon( "disconnect" ); self endon( "zombified" ); - chest = eObj.eEnt; + chest = eObj.eent; self thread WatchForCancel( chest ); @@ -123,7 +123,7 @@ Executer( eObj ) self ClearScriptGoal(); self ClearPriorityObjective(); - self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); + self CompletedObjective( eObj.bwassuccessful, eObj.sreason ); } WatchForCancelCleanup() @@ -162,13 +162,13 @@ WatchToGoToChest( chest ) { wait 0.05; - if ( self IsTouching( chest ) || chest PointInsideUseTrigger( self.origin ) ) + if ( self istouching( chest ) || chest PointInsideUseTrigger( self.origin ) ) { self notify( "goal" ); break; // is this needed? } - if ( isDefined( chest.disabled ) && chest.disabled ) + if ( isdefined( chest.disabled ) && chest.disabled ) { self notify( "bad_path" ); break; // is this needed? @@ -180,14 +180,14 @@ GoDoTreasureChest( eObj ) { self endon( "cancel_bot_objective" ); - chest = eObj.eEnt; + chest = eObj.eent; lid = getent( chest.target, "targetname" ); weapon_spawn_org = getent( lid.target, "targetname" ); org = self getOffset( lid ); - weap = self GetCurrentWeapon(); + weap = self getcurrentweapon(); - if ( weap == "none" || !self getAmmoCount( weap ) ) + if ( weap == "none" || !self getammocount( weap ) ) { self SetPriorityObjective(); } @@ -200,13 +200,13 @@ GoDoTreasureChest( eObj ) if ( result != "goal" ) { - eObj.sReason = "didn't go to chest"; + eObj.sreason = "didn't go to chest"; return; } - if ( !self IsTouching( chest ) && !chest PointInsideUseTrigger( self.origin ) ) + if ( !self istouching( chest ) && !chest PointInsideUseTrigger( self.origin ) ) { - eObj.sReason = "not touching chest"; + eObj.sreason = "not touching chest"; return; } @@ -225,9 +225,9 @@ GoDoTreasureChest( eObj ) self ClearPriorityObjective(); // randomization isnt happening... - if ( !isDefined( chest.disabled ) || !chest.disabled ) + if ( !isdefined( chest.disabled ) || !chest.disabled ) { - eObj.sReason = "chest isnt randomizing"; + eObj.sreason = "chest isnt randomizing"; return; } @@ -235,13 +235,13 @@ GoDoTreasureChest( eObj ) if (ret == "timeout") { - eObj.sReason = "randomization_done timed out"; + eObj.sreason = "randomization_done timed out"; return; } - if ( isDefined( level.flag[ "moving_chest_now" ] ) && flag( "moving_chest_now" ) ) + if ( isdefined( level.flag[ "moving_chest_now" ] ) && flag( "moving_chest_now" ) ) { - eObj.sReason = "chest is moving!"; + eObj.sreason = "chest is moving!"; return; } @@ -258,13 +258,13 @@ GoDoTreasureChest( eObj ) if ( result != "goal" ) { - eObj.sReason = "didn't go to chest"; + eObj.sreason = "didn't go to chest"; return; } - if ( !self IsTouching( chest ) && !chest PointInsideUseTrigger( self.origin ) ) + if ( !self istouching( chest ) && !chest PointInsideUseTrigger( self.origin ) ) { - eObj.sReason = "not touching chest"; + eObj.sreason = "not touching chest"; return; } @@ -279,6 +279,6 @@ GoDoTreasureChest( eObj ) wait 0.1; // complete! - eObj.sReason = "completed " + weap; - eObj.bWasSuccessful = true; + eObj.sreason = "completed " + weap; + eObj.bwassuccessful = true; } diff --git a/maps/bots/objectives/_utility.gsc b/maps/bots/objectives/_utility.gsc index 2643c61..3a8a030 100644 --- a/maps/bots/objectives/_utility.gsc +++ b/maps/bots/objectives/_utility.gsc @@ -4,43 +4,43 @@ CreateObjectiveForManger( sName, fpFinder, fpPriorty, fpExecuter, iProcessRate ) { - Answer = SpawnStruct(); + Answer = spawnstruct(); - Answer.sName = sName; - Answer.fpFinder = fpFinder; - Answer.fpExecuter = fpExecuter; - Answer.fpPriorty = fpPriorty; + Answer.sname = sName; + Answer.fpfinder = fpFinder; + Answer.fpexecuter = fpExecuter; + Answer.fppriorty = fpPriorty; - Answer.aBotProcessTimes = []; - Answer.iProcessRate = iProcessRate; + Answer.abotprocesstimes = []; + Answer.iprocessrate = iProcessRate; return Answer; } CreateFinderObjectiveEZ( eObj, eEnt ) { - return self CreateFinderObjective( eObj, eObj.sName + "_" + eEnt GetEntityNumber(), eEnt, self [[eObj.fpPriorty]]( eObj, eEnt ) ); + return self CreateFinderObjective( eObj, eObj.sname + "_" + eEnt getentitynumber(), eEnt, self [[eObj.fppriorty]]( eObj, eEnt ) ); } CreateFinderObjective( eObj, sName, eEnt, fPriority ) { - Answer = SpawnStruct(); + Answer = spawnstruct(); - Answer.eParentObj = eObj; - Answer.sName = sName; - Answer.eEnt = eEnt; - Answer.fPriority = fPriority; - Answer.GUID = eEnt GetEntityNumber(); + Answer.eparentobj = eObj; + Answer.sname = sName; + Answer.eent = eEnt; + Answer.fpriority = fPriority; + Answer.guid = eEnt getentitynumber(); - Answer.bWasSuccessful = false; - Answer.sReason = "canceled"; + Answer.bwassuccessful = false; + Answer.sreason = "canceled"; return Answer; } GetBotsAmountForEntity( eEnt ) { - if ( !isDefined( eEnt.bots ) ) + if ( !isdefined( eEnt.bots ) ) { eEnt.bots = 0; } @@ -56,7 +56,7 @@ IncrementBotsForEntity( eEnt ) self waittill_either( "disconnect", "zombified" ); - if ( isDefined( eEnt ) ) + if ( isdefined( eEnt ) ) { eEnt.bots--; } @@ -66,7 +66,7 @@ DecrementBotsForEntity( eEnt ) { self notify( "bots_for_entity_cleanup" ); - if ( isDefined( eEnt ) ) + if ( isdefined( eEnt ) ) { eEnt.bots--; } @@ -94,7 +94,7 @@ GetBotObjectiveEnt() return undefined; } - return self GetBotObjective().eEnt; + return self GetBotObjective().eent; } /* @@ -110,5 +110,5 @@ GetBotObjective() */ HasBotObjective() { - return isDefined( self GetBotObjective() ); + return isdefined( self GetBotObjective() ); } diff --git a/maps/bots/objectives/_wallweapon.gsc b/maps/bots/objectives/_wallweapon.gsc index 80f5951..57f6403 100644 --- a/maps/bots/objectives/_wallweapon.gsc +++ b/maps/bots/objectives/_wallweapon.gsc @@ -12,14 +12,14 @@ Finder( eObj ) return answer; } - weapon_spawns = GetEntArray( "weapon_upgrade", "targetname" ); + weapon_spawns = getentarray( "weapon_upgrade", "targetname" ); - if ( !isDefined( weapon_spawns ) || weapon_spawns.size <= 0 ) + if ( !isdefined( weapon_spawns ) || weapon_spawns.size <= 0 ) { return answer; } - weapons = self GetWeaponsList(); + weapons = self getweaponslist(); // TODO check if need a new weapon, rate weapons too is better then current etc @@ -27,7 +27,7 @@ Finder( eObj ) { player_has_weapon = false; - if ( !isDefined( weapon_spawns[i].zombie_weapon_upgrade ) ) + if ( !isdefined( weapon_spawns[i].zombie_weapon_upgrade ) ) { continue; } @@ -40,7 +40,7 @@ Finder( eObj ) } } - is_grenade = ( WeaponType( weapon_spawns[i].zombie_weapon_upgrade ) == "grenade" ); + is_grenade = ( weapontype( weapon_spawns[i].zombie_weapon_upgrade ) == "grenade" ); if ( !player_has_weapon || is_grenade ) { @@ -63,12 +63,12 @@ Finder( eObj ) model = weapon_spawns[ i ]; - if ( isDefined( weapon_spawns[ i ].target ) ) + if ( isdefined( weapon_spawns[ i ].target ) ) { - model = getEnt( weapon_spawns[ i ].target, "targetname" ); + model = getent( weapon_spawns[ i ].target, "targetname" ); } - if ( !isDefined( model ) ) + if ( !isdefined( model ) ) { continue; } @@ -112,7 +112,7 @@ Priority( eObj, eEnt ) base_priority -= 1; } - if ( isSubStr( eEnt.zombie_weapon_upgrade, "kar98k" ) || isSubStr( eEnt.zombie_weapon_upgrade, "type99" ) ) + if ( issubstr( eEnt.zombie_weapon_upgrade, "kar98k" ) || issubstr( eEnt.zombie_weapon_upgrade, "type99" ) ) { base_priority -= 999; } @@ -125,7 +125,7 @@ Executer( eObj ) self endon( "disconnect" ); self endon( "zombified" ); - weapon = eObj.eEnt; + weapon = eObj.eent; self thread WatchForCancel( weapon ); @@ -136,7 +136,7 @@ Executer( eObj ) self ClearScriptGoal(); self ClearPriorityObjective(); - self CompletedObjective( eObj.bWasSuccessful, eObj.sReason ); + self CompletedObjective( eObj.bwassuccessful, eObj.sreason ); } WatchForCancelCleanup() @@ -175,7 +175,7 @@ WatchToGoToWeapon( weapon ) { wait 0.05; - if ( self IsTouching( weapon ) || weapon PointInsideUseTrigger( self.origin ) ) + if ( self istouching( weapon ) || weapon PointInsideUseTrigger( self.origin ) ) { self notify( "goal" ); break; // is this needed? @@ -187,19 +187,19 @@ GoDoWallweapon( eObj ) { self endon( "cancel_bot_objective" ); - weapon = eObj.eEnt; + weapon = eObj.eent; model = weapon; - if ( isDefined( weapon.target ) ) + if ( isdefined( weapon.target ) ) { - model = getEnt( weapon.target, "targetname" ); + model = getent( weapon.target, "targetname" ); } org = self getOffset( model, weapon ); - weap = self GetCurrentWeapon(); + weap = self getcurrentweapon(); - if ( weap == "none" || !self getAmmoCount( weap ) ) + if ( weap == "none" || !self getammocount( weap ) ) { self SetPriorityObjective(); } @@ -212,13 +212,13 @@ GoDoWallweapon( eObj ) if ( result != "goal" ) { - eObj.sReason = "didn't go to weapon"; + eObj.sreason = "didn't go to weapon"; return; } - if ( !self IsTouching( weapon ) && !weapon PointInsideUseTrigger( self.origin ) ) + if ( !self istouching( weapon ) && !weapon PointInsideUseTrigger( self.origin ) ) { - eObj.sReason = "not touching weapon"; + eObj.sreason = "not touching weapon"; return; } @@ -232,6 +232,6 @@ GoDoWallweapon( eObj ) self thread BotPressUse( 0.15 ); wait 0.1; - eObj.sReason = "completed"; - eObj.bWasSuccessful = true; + eObj.sreason = "completed"; + eObj.bwassuccessful = true; } diff --git a/scripts/sp/bots_adapter_pt4.gsc b/scripts/sp/bots_adapter_pt4.gsc index b944089..6750b6e 100644 --- a/scripts/sp/bots_adapter_pt4.gsc +++ b/scripts/sp/bots_adapter_pt4.gsc @@ -23,57 +23,57 @@ init() do_printconsole( s ) { - PrintConsole( s ); + printconsole( s ); } do_botaction( action ) { - self BotAction( action ); + self botaction( action ); } do_botstop() { - self BotStop(); + self botstop(); } do_botmovement( left, forward ) { - self BotMovement( left, forward ); + self botmovement( left, forward ); } do_botmeleeparams( yaw, dist ) { - // self BotMeleeParams( yaw, dist ); + // self botmeleeparams( yaw, dist ); } do_isbot() { - return self isBot(); + return self isbot(); } do_generatepath( from, to, team, best_effort ) { - return GeneratePath( from, to, team, best_effort ); + return generatepath( from, to, team, best_effort ); } do_getfunction( file, threadname ) { - return GetFunction( file, threadname ); + return getfunction( file, threadname ); } do_getmins() { - return self GetMins(); + return self getmins(); } do_getmaxs() { - return self GetMaxs(); + return self getmaxs(); } do_getguid() { - return self GetGuid(); + return self getguid(); } do_setallowedtraversals( a ) @@ -88,12 +88,12 @@ do_setignoredlinks( a ) do_getnodenumber() { - return self GetNodeNumber(); + return self getnodenumber(); } do_getlinkednodes() { - return self GetLinkedNodes(); + return self getlinkednodes(); } do_addtestclient() @@ -113,5 +113,5 @@ do_cmdexec( a ) do_ishost() { - return self isHost(); + return self ishost(); }