From 8ec1385d1883a6385ce5c85e0436f408293d7752 Mon Sep 17 00:00:00 2001 From: ineed bots Date: Fri, 22 Dec 2023 01:28:59 -0600 Subject: [PATCH] curly braces --- maps/mp/bots/_bot.gsc | 204 +++++ maps/mp/bots/_bot_chat.gsc | 113 ++- maps/mp/bots/_bot_internal.gsc | 438 +++++++++- maps/mp/bots/_bot_script.gsc | 1459 ++++++++++++++++++++++++++++++++ maps/mp/bots/_bot_utility.gsc | 306 +++++++ maps/mp/bots/_menu.gsc | 174 ++++ maps/mp/bots/_wp_editor.gsc | 84 ++ 7 files changed, 2774 insertions(+), 4 deletions(-) diff --git a/maps/mp/bots/_bot.gsc b/maps/mp/bots/_bot.gsc index d36a3e3..41c3965 100644 --- a/maps/mp/bots/_bot.gsc +++ b/maps/mp/bots/_bot.gsc @@ -18,127 +18,207 @@ init() level.bw_VERSION = "2.1.0"; if ( getDvar( "bots_main" ) == "" ) + { setDvar( "bots_main", true ); + } if ( !getDvarInt( "bots_main" ) ) + { return; + } if ( !wait_for_builtins() ) + { 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_firstIsHost" ) == "" ) + { setDvar( "bots_main_firstIsHost", false ); //first play 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_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_fill" ) == "" ) + { setDvar( "bots_manage_fill", 0 ); //amount of bots to maintain + } if ( getDvar( "bots_manage_fill_spec" ) == "" ) + { setDvar( "bots_manage_fill_spec", true ); //to count for fill if player is on spec team + } 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_team" ) == "" ) + { setDvar( "bots_team", "autoassign" ); //which team for bots to join + } if ( getDvar( "bots_team_amount" ) == "" ) + { setDvar( "bots_team_amount", 0 ); //amount of bots on axis team + } if ( getDvar( "bots_team_force" ) == "" ) + { setDvar( "bots_team_force", false ); //force bots on team + } if ( getDvar( "bots_team_mode" ) == "" ) + { setDvar( "bots_team_mode", 0 ); //counts just bots when 1 + } 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_axis_hard" ) == "" ) + { setDvar( "bots_skill_axis_hard", 0 ); //amount of hard bots on axis team + } if ( getDvar( "bots_skill_axis_med" ) == "" ) + { setDvar( "bots_skill_axis_med", 0 ); + } if ( getDvar( "bots_skill_allies_hard" ) == "" ) + { setDvar( "bots_skill_allies_hard", 0 ); + } if ( getDvar( "bots_skill_allies_med" ) == "" ) + { setDvar( "bots_skill_allies_med", 0 ); + } if ( getDvar( "bots_skill_min" ) == "" ) + { setDvar( "bots_skill_min", 1 ); + } if ( getDvar( "bots_skill_max" ) == "" ) + { setDvar( "bots_skill_max", 7 ); + } if ( getDvar( "bots_loadout_reasonable" ) == "" ) //filter out the bad 'guns' and perks + { setDvar( "bots_loadout_reasonable", false ); + } if ( getDvar( "bots_loadout_allow_op" ) == "" ) //allows jug, marty and laststand + { setDvar( "bots_loadout_allow_op", true ); + } 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_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_fire" ) == "" ) //bots fire + { setDvar( "bots_play_fire", true ); + } if ( getDvar( "bots_play_nade" ) == "" ) //bots grenade + { setDvar( "bots_play_nade", true ); + } if ( getDvar( "bots_play_take_carepackages" ) == "" ) //bots take carepackages + { setDvar( "bots_play_take_carepackages", true ); + } if ( getDvar( "bots_play_obj" ) == "" ) //bots play the obj + { setDvar( "bots_play_obj", true ); + } if ( getDvar( "bots_play_camp" ) == "" ) //bots camp and follow + { setDvar( "bots_play_camp", true ); + } if ( getDvar( "bots_play_jumpdrop" ) == "" ) //bots jump and dropshot + { setDvar( "bots_play_jumpdrop", true ); + } if ( getDvar( "bots_play_target_other" ) == "" ) //bot target non play ents (vehicles) + { setDvar( "bots_play_target_other", true ); + } if ( getDvar( "bots_play_killstreak" ) == "" ) //bot use killstreaks + { setDvar( "bots_play_killstreak", true ); + } if ( getDvar( "bots_play_ads" ) == "" ) //bot ads + { setDvar( "bots_play_ads", true ); + } if ( getDvar( "bots_play_aim" ) == "" ) + { setDvar( "bots_play_aim", true ); + } if ( !isDefined( game["botWarfare"] ) ) + { game["botWarfare"] = true; + } level.defuseObject = undefined; level.bots_smokeList = List(); @@ -212,12 +292,16 @@ handleBots() level addBots(); while ( !level.intermission ) + { wait 0.05; + } setDvar( "bots_manage_add", getBotArray().size ); if ( !getDvarInt( "bots_main_kickBotsAtEnd" ) ) + { return; + } bots = getBotArray(); @@ -279,7 +363,9 @@ fixGamemodes() if ( isDefined( level.bombZones ) && level.gametype == "sd" ) { for ( i = 0; i < level.bombZones.size; i++ ) + { level.bombZones[i].onUse = ::onUsePlantObjectFix; + } break; } @@ -317,9 +403,13 @@ fixDem() bombzone = level.bombZones[i]; if ( isDefined( bombzone.trigger.trigger_off ) ) + { bombzone.bombExploded = true; + } else + { bombzone.bombExploded = undefined; + } } wait 0.05; @@ -345,14 +435,18 @@ fixKoth() for ( i = level.radios.size - 1; i >= 0; i-- ) { if ( level.radioObject != level.radios[i].gameobject ) + { continue; + } level.radio = level.radios[i]; break; } while ( isDefined( level.radioObject ) && level.radio.gameobject == level.radioObject ) + { wait 0.05; + } } } @@ -368,7 +462,9 @@ addNotifyOnAirdrops_loop() airdrop = dropCrates[i]; if ( isDefined( airdrop.doingPhysics ) ) + { continue; + } airdrop.doingPhysics = true; airdrop thread doNotifyOnAirdrop(); @@ -398,7 +494,9 @@ doNotifyOnAirdrop() self.doingPhysics = false; if ( isDefined( self.owner ) ) + { self.owner notify( "crate_physics_done" ); + } self thread onCarepackageCaptured(); } @@ -452,23 +550,33 @@ watchScrabler_loop() player = level.players[i]; if ( !player _HasPerk( "specialty_localjammer" ) || !isReallyAlive( player ) ) + { continue; + } if ( player isEMPed() ) + { continue; + } for ( h = level.players.size - 1; h >= 0; h-- ) { player2 = level.players[h]; if ( player2 == player ) + { continue; + } if ( level.teamBased && player2.team == player.team ) + { continue; + } if ( DistanceSquared( player2.origin, player.origin ) > 256 * 256 ) + { continue; + } player2.bot_isScrambled = true; } @@ -506,10 +614,14 @@ connected() self endon( "disconnect" ); if ( !isDefined( self.pers["bot_host"] ) ) + { self thread doHostCheck(); + } if ( !self is_bot() ) + { return; + } if ( !isDefined( self.pers["isBot"] ) ) { @@ -550,25 +662,39 @@ watchBotDebugEvent() big_str = "Bot Warfare debug: " + self.name + ": " + msg; if ( isDefined( str ) && isString( str ) ) + { big_str += ", " + str; + } if ( isDefined( b ) && isString( b ) ) + { big_str += ", " + b; + } if ( isDefined( c ) && isString( c ) ) + { big_str += ", " + c; + } if ( isDefined( d ) && isString( d ) ) + { big_str += ", " + d; + } if ( isDefined( e ) && isString( e ) ) + { big_str += ", " + e; + } if ( isDefined( f ) && isString( f ) ) + { big_str += ", " + f; + } if ( isDefined( g ) && isString( g ) ) + { big_str += ", " + g; + } BotBuiltinPrintConsole( big_str ); } @@ -630,10 +756,14 @@ diffBots_loop() player = level.players[i]; if ( !isDefined( player.pers["team"] ) ) + { continue; + } if ( !player is_bot() ) + { continue; + } if ( player.pers["team"] == "axis" ) { @@ -648,7 +778,9 @@ diffBots_loop() player.pers["bots"]["skill"]["base"] = 4; } else + { player.pers["bots"]["skill"]["base"] = 1; + } } else if ( player.pers["team"] == "allies" ) { @@ -663,7 +795,9 @@ diffBots_loop() player.pers["bots"]["skill"]["base"] = 4; } else + { player.pers["bots"]["skill"]["base"] = 1; + } } } } @@ -676,7 +810,9 @@ diffBots_loop() player = level.players[i]; if ( !player is_bot() ) + { continue; + } player.pers["bots"]["skill"]["base"] = var_skill; } @@ -691,7 +827,9 @@ diffBots_loop() player = level.players[i]; if ( !player is_bot() ) + { continue; + } player.pers["bots"]["skill"]["base"] = int( clamp( player.pers["bots"]["skill"]["base"], min_diff, max_diff ) ); } @@ -730,21 +868,31 @@ teamBots_loop() player = level.players[i]; if ( !isDefined( player.pers["team"] ) ) + { continue; + } if ( player is_bot() ) { if ( player.pers["team"] == "allies" ) + { alliesbots++; + } else if ( player.pers["team"] == "axis" ) + { axisbots++; + } } else { if ( player.pers["team"] == "allies" ) + { alliesplayers++; + } else if ( player.pers["team"] == "axis" ) + { axisplayers++; + } } } @@ -768,7 +916,9 @@ teamBots_loop() toTeam = "axis"; if ( axis > allies ) + { toTeam = "allies"; + } } } @@ -781,20 +931,32 @@ teamBots_loop() player = level.players[i]; if ( !isDefined( player.pers["team"] ) ) + { continue; + } if ( !player is_bot() ) + { continue; + } if ( player.pers["team"] == toTeam ) + { continue; + } if ( toTeam == "allies" ) + { player thread [[level.allies]](); + } else if ( toTeam == "axis" ) + { player thread [[level.axis]](); + } else + { player thread [[level.spectator]](); + } break; } @@ -810,10 +972,14 @@ teamBots_loop() player = level.players[i]; if ( !isDefined( player.pers["team"] ) ) + { continue; + } if ( !player is_bot() ) + { continue; + } if ( player.pers["team"] == "axis" ) { @@ -864,7 +1030,9 @@ addBots_loop() SetDvar( "bots_manage_add", 0 ); if ( botsToAdd > 64 ) + { botsToAdd = 64; + } for ( ; botsToAdd > 0; botsToAdd-- ) { @@ -876,7 +1044,9 @@ addBots_loop() fillMode = getDVarInt( "bots_manage_fill_mode" ); if ( fillMode == 2 || fillMode == 3 ) + { setDvar( "bots_manage_fill", getGoodMapAmount() ); + } fillAmount = getDvarInt( "bots_manage_fill" ); @@ -891,11 +1061,17 @@ addBots_loop() player = level.players[i]; if ( player is_bot() ) + { bots++; + } else if ( !isDefined( player.pers["team"] ) || ( player.pers["team"] != "axis" && player.pers["team"] != "allies" ) ) + { spec++; + } else + { players++; + } } if ( !randomInt( 999 ) ) @@ -918,15 +1094,23 @@ addBots_loop() player = level.players[i]; if ( player is_bot() ) + { continue; + } if ( !isDefined( player.pers["team"] ) ) + { continue; + } if ( player.pers["team"] == "axis" ) + { axisplayers++; + } else if ( player.pers["team"] == "allies" ) + { alliesplayers++; + } } result = fillAmount - abs( axisplayers - alliesplayers ) + bots; @@ -934,11 +1118,17 @@ addBots_loop() if ( players == 0 ) { if ( bots < fillAmount ) + { result = fillAmount - 1; + } else if ( bots > fillAmount ) + { result = fillAmount + 1; + } else + { result = fillAmount; + } } bots = result; @@ -947,19 +1137,27 @@ addBots_loop() amount = bots; if ( fillMode == 0 || fillMode == 2 ) + { amount += players; + } if ( getDVarInt( "bots_manage_fill_spec" ) ) + { amount += spec; + } if ( amount < fillAmount ) + { setDvar( "bots_manage_add", 1 ); + } else if ( amount > fillAmount && getDvarInt( "bots_manage_fill_kick" ) ) { tempBot = getBotToKick(); if ( isDefined( tempBot ) ) + { kick( tempBot getEntityNumber(), "EXE_PLAYERKICKED" ); + } } } @@ -992,14 +1190,20 @@ onGrenadeFire() self waittill ( "grenade_fire", grenade, weaponName ); if ( !isDefined( grenade ) ) + { continue; + } grenade.name = weaponName; if ( weaponName == "smoke_grenade_mp" ) + { grenade thread AddToSmokeList(); + } else if ( isSubStr( weaponName, "frag_" ) ) + { grenade thread AddToFragList( self ); + } } } diff --git a/maps/mp/bots/_bot_chat.gsc b/maps/mp/bots/_bot_chat.gsc index 74d6544..9d95af2 100644 --- a/maps/mp/bots/_bot_chat.gsc +++ b/maps/mp/bots/_bot_chat.gsc @@ -16,7 +16,9 @@ init() { if ( getDvar( "bots_main_chat" ) == "" ) + { setDvar( "bots_main_chat", 1.0 ); + } level thread onBotConnected(); } @@ -42,15 +44,20 @@ BotDoChat( chance, string, isTeam ) mod = getDvarFloat( "bots_main_chat" ); if ( mod <= 0.0 ) + { return; + } - if ( chance >= 100 || mod >= 100.0 || - ( RandomInt( 100 ) < ( chance * mod ) + 0 ) ) + if ( chance >= 100 || mod >= 100.0 || ( RandomInt( 100 ) < ( chance * mod ) + 0 ) ) { if ( isDefined( isTeam ) && isTeam ) + { self sayteam( string ); + } else + { self sayall( string ); + } } } @@ -81,7 +88,9 @@ start_onnuke_call() for ( ;; ) { while ( !isDefined( level.nukeIncoming ) && !isDefined( level.moabIncoming ) ) + { wait 0.05 + randomInt( 4 ); + } self thread bot_onnukecall_watch(); @@ -132,7 +141,9 @@ start_random_chat() if ( randomInt( 100 ) < 1 ) { if ( randomInt( 100 ) < 1 && isReallyAlive( self ) ) + { self thread doQuickMessage(); + } } } } @@ -474,7 +485,9 @@ hasKillstreak( streakname ) loadoutKillstreak3 = self getPlayerData( "killstreaks", 2 ); if ( loadoutKillstreak1 == streakname || loadoutKillstreak2 == streakname || loadoutKillstreak3 == streakname ) + { return true; + } return false; } @@ -533,7 +546,9 @@ doQuickMessage() else { if ( randomint( 100 ) < 1 ) + { self BotDoChat( 1, maps\mp\bots\_bot_utility::keyCodeToString( 2 ) + maps\mp\bots\_bot_utility::keyCodeToString( 17 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 3 ) + maps\mp\bots\_bot_utility::keyCodeToString( 8 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 8 ) + maps\mp\bots\_bot_utility::keyCodeToString( 13 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 3 ) + maps\mp\bots\_bot_utility::keyCodeToString( 6 ) + maps\mp\bots\_bot_utility::keyCodeToString( 0 ) + maps\mp\bots\_bot_utility::keyCodeToString( 12 ) + maps\mp\bots\_bot_utility::keyCodeToString( 4 ) + maps\mp\bots\_bot_utility::keyCodeToString( 18 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 5 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 17 ) + maps\mp\bots\_bot_utility::keyCodeToString( 27 ) + maps\mp\bots\_bot_utility::keyCodeToString( 1 ) + maps\mp\bots\_bot_utility::keyCodeToString( 14 ) + maps\mp\bots\_bot_utility::keyCodeToString( 19 ) + maps\mp\bots\_bot_utility::keyCodeToString( 18 ) + maps\mp\bots\_bot_utility::keyCodeToString( 26 ) ); + } } self.spamdelay = undefined; @@ -650,25 +665,41 @@ endgame_chat() case 17: if ( self == winner ) + { self BotDoChat( 20, "LOL we wouldn't of won without me!" ); + } else if ( self == loser ) + { self BotDoChat( 20, "damn i sucked but i still won" ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, "lol " + loser.name + " sucked hard!" ); + } else if ( self != winner ) + { self BotDoChat( 20, "wow " + winner.name + " did very well!" ); + } break; case 18: if ( self == winner ) + { self BotDoChat( 20, "I'm the VERY BEST!" ); + } else if ( self == loser ) + { self BotDoChat( 20, "lol my team is good, i suck doe" ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, "lol " + loser.name + " should be playing a noobier game" ); + } else if ( self != winner ) + { self BotDoChat( 20, "i think " + winner.name + " is a hacker" ); + } break; @@ -745,25 +776,41 @@ endgame_chat() case 14: if ( self == winner ) + { self BotDoChat( 20, "LOL we lost even with my score." ); + } else if ( self == loser ) + { self BotDoChat( 20, "damn im probally the reason we lost" ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, loser.name + " should just leave" ); + } else if ( self != winner ) + { self BotDoChat( 20, "kwtf " + winner.name + " is a hacker" ); + } break; case 15: if ( self == winner ) + { self BotDoChat( 20, "my teammates are garabge" ); + } else if ( self == loser ) + { self BotDoChat( 20, "lol im garbage" ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, loser.name + " sux" ); + } else if ( self != winner ) + { self BotDoChat( 20, winner.name + " is a noob!" ); + } break; @@ -833,37 +880,61 @@ endgame_chat() { case 0: if ( self == winner ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Haha Suck it, you all just got pwnd!" ); + } else if ( self == loser ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Lol i Sucked in this game, just look at my score!" ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "gga, Bad luck " + loser.name ); + } else if ( self != winner ) + { self BotDoChat( 20, "This game sucked, " + winner.name + " is such a hacker!!" ); + } break; case 1: if ( self == winner ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "LOL i just wasted you all!! Whoot whoot!" ); + } else if ( self == loser ) + { self BotDoChat( 20, "GGA i suck, Nice score " + winner.name ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Rofl, " + loser.name + " dude, you suck!!" ); + } else if ( self != winner ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Nice Score " + winner.name + ", how did you get to be so good?" ); + } break; case 2: if ( self == winner ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "LOL i just wasted you all!! Whoot whoot!" ); + } else if ( self == loser ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "nice wallhacks " + winner.name ); + } else if ( self != loser && randomint( 2 ) == 1 ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "Lol atleast i did better then " + loser.name ); + } else if ( self != winner ) + { self BotDoChat( 20, "^" + ( randomint( 6 ) + 1 ) + "lolwtf " + winner.name ); + } break; @@ -949,17 +1020,25 @@ bot_onnukecall_watch() { case 0: if ( level.nukeInfo.player != self ) + { self BotDoChat( 30, "Wow who got a nuke?" ); + } else + { self BotDoChat( 30, "NUUUUUUKKKKKKEEEEEE!!!! :D" ); + } break; case 1: if ( level.nukeInfo.player != self ) + { self BotDoChat( 30, "lol " + level.nukeInfo.player.name + " is a hacker" ); + } else + { self BotDoChat( 30, "im the best!" ); + } break; @@ -969,9 +1048,13 @@ bot_onnukecall_watch() case 3: if ( level.nukeInfo.team != self.team ) + { self BotDoChat( 30, "man my team sucks ):" ); + } else + { self BotDoChat( 30, "man my team is good lol" ); + } break; } @@ -1014,9 +1097,13 @@ bot_chat_streak( streakCount ) else { if ( GetDvarInt( "bots_loadout_allow_op" ) ) + { self BotDoChat( 100, "Come on! I would of had a nuke but I don't got it set..." ); + } else + { self BotDoChat( 100, "WOW.. I could have a nuke but dumb admin disabled it for bots." ); + } } } } @@ -1029,7 +1116,9 @@ bot_chat_killed_watch( victim ) self endon( "disconnect" ); if ( !isDefined( victim ) || !isDefined( victim.name ) ) + { return; + } message = ""; @@ -1197,7 +1286,9 @@ bot_chat_killed_watch( victim ) case 40: if ( isDefined( victim.attackerData ) && isDefined( victim.attackerData[self.guid] ) && isDefined( victim.attackerData[self.guid].weapon ) ) + { message = ( "Man, I sure love my " + getBaseWeaponName( victim.attackerData[self.guid].weapon ) + "!" ); + } break; @@ -1218,7 +1309,9 @@ bot_chat_death_watch( killer, last_ks ) self endon( "disconnect" ); if ( !isDefined( killer ) || !isDefined( killer.name ) ) + { return; + } message = ""; @@ -1242,9 +1335,13 @@ bot_chat_death_watch( killer, last_ks ) case 4: if ( last_ks > 0 ) + { message = ( "^" + ( randomint( 6 ) + 1 ) + "Nooooooooo my killstreaks!! :( I had a " + last_ks + " killstreak!!" ); + } else + { message = ( "man im getting spawn killed, i have a " + self.pers["cur_death_streak"] + " deathstreak!" ); + } break; @@ -1470,7 +1567,9 @@ bot_chat_death_watch( killer, last_ks ) case 60: if ( isDefined( self.attackerData ) && isDefined( self.attackerData[killer.guid] ) && isDefined( self.attackerData[killer.guid].weapon ) ) + { message = "Wow! Nice " + getBaseWeaponName( self.attackerData[killer.guid].weapon ) + " you got there, " + killer.name + "!"; + } break; @@ -1837,9 +1936,13 @@ bot_chat_crate_cap_watch( state, aircare, player, d, e, f, g ) { case 0: if ( !isDefined( aircare.owner ) || aircare.owner == self ) + { self BotDoChat( 5, "going to my carepackage" ); + } else + { self BotDoChat( 5, "going to " + aircare.owner.name + "'s carepackage" ); + } break; @@ -1855,9 +1958,13 @@ bot_chat_crate_cap_watch( state, aircare, player, d, e, f, g ) { case 0: if ( !isDefined( aircare.owner ) || aircare.owner == self ) + { self BotDoChat( 15, "taking my carepackage" ); + } else + { self BotDoChat( 15, "taking " + aircare.owner.name + "'s carepackage" ); + } break; @@ -2032,7 +2139,9 @@ bot_chat_attack_vehicle_watch( state, vehicle, rocketAmmo, d, e, f, g ) weap = rocketAmmo; if ( !isDefined( weap ) ) + { weap = self getCurrentWeapon(); + } self BotDoChat( 10, "Im going to takedown your ks with my " + getBaseWeaponName( weap ) ); break; diff --git a/maps/mp/bots/_bot_internal.gsc b/maps/mp/bots/_bot_internal.gsc index 08b78fe..6f66f56 100644 --- a/maps/mp/bots/_bot_internal.gsc +++ b/maps/mp/bots/_bot_internal.gsc @@ -178,7 +178,9 @@ onPlayerSpawned() SetWeaponDistMulti( weap ) { if ( weap == "none" ) + { return 1; + } switch ( weaponClass( weap ) ) { @@ -202,10 +204,14 @@ SetWeaponDistMulti( weap ) IsWeapSniper( weap ) { if ( weap == "none" ) + { return false; + } if ( weaponClass( weap ) != "sniper" ) + { return false; + } return true; } @@ -230,7 +236,9 @@ onWeaponChange() 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 ); @@ -251,15 +259,21 @@ reload_watch_loop() 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; @@ -309,12 +323,16 @@ onLastStand() while ( true ) { while ( !self inLastStand() ) + { wait 0.05; + } self notify( "kill_goal" ); while ( self inLastStand() ) + { wait 0.05; + } } } @@ -331,10 +349,14 @@ watchUsingRemote() wait 1; if ( !isAlive( self ) ) + { return; + } if ( !self IsUsingRemote() ) + { continue; + } if ( isDefined( level.chopper ) && isDefined( level.chopper.gunner ) && level.chopper.gunner == self ) { @@ -367,7 +389,9 @@ watchUsingMinigun() } if ( isDefined( self.bot.target ) ) + { self thread pressFire(); + } wait 0.05; } @@ -387,10 +411,14 @@ watchAc130Weapon() curWeap = self GetCurrentWeapon(); if ( curWeap != "ac130_105mm_mp" && curWeap != "ac130_40mm_mp" && curWeap != "ac130_25mm_mp" ) + { self switchToWeapon( "ac130_105mm_mp" ); + } if ( isDefined( self.bot.target ) ) + { self thread pressFire(); + } wait 0.05; } @@ -454,12 +482,16 @@ watchPickupGun() wait 1; if ( self UseButtonPressed() ) + { continue; + } weap = self GetCurrentWeapon(); if ( weap != "none" && self GetAmmoCount( weap ) ) + { continue; + } self thread use( 0.5 ); } @@ -478,10 +510,14 @@ watchGrenadeFire() self waittill( "grenade_fire", nade, weapname ); if ( !isDefined( nade ) ) + { continue; + } if ( weapname == "c4_mp" ) + { self thread watchC4Thrown( nade ); + } } } @@ -506,28 +542,42 @@ watchC4Thrown( c4 ) player = level.players[i]; if ( player == self ) + { continue; + } if ( ( level.teamBased && self.team == player.team ) || player.sessionstate != "playing" || !isReallyAlive( player ) ) + { continue; + } if ( distanceSquared( c4.origin, player.origin ) > 200 * 200 ) + { continue; + } if ( !bulletTracePassed( c4.origin, player.origin + ( 0, 0, 25 ), false, c4 ) ) + { continue; + } shouldBreak = true; } if ( shouldBreak ) + { break; + } } if ( self getCurrentWeapon() != "c4_mp" ) + { self notify( "alt_detonate" ); + } else + { self thread pressFire(); + } } /* @@ -599,12 +649,16 @@ doBotMovement_loop( data ) { // 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] ) ); } @@ -642,7 +696,9 @@ watchHoldBreath() wait 1; if ( self.bot.isfrozen ) + { continue; + } self holdbreath( self playerADS() > 0 ); } @@ -660,16 +716,24 @@ grenade_danager_loop() frag = level.bots_fragList.data[i]; if ( level.teamBased && frag.team == self.team ) + { continue; + } if ( lengthSquared( frag.velocity ) > 10000 ) + { continue; + } if ( DistanceSquared( self.origin, frag.origin ) > 20000 ) + { continue; + } if ( !bulletTracePassed( myEye, frag.origin, false, frag.grenade ) ) + { continue; + } self BotNotifyBotEvent( "throwback", "stop", frag ); self thread frag(); @@ -690,19 +754,29 @@ grenade_danager() wait 1; if ( self inLastStand() && !self _hasPerk( "specialty_laststandoffhand" ) && !self inFinalStand() ) + { continue; + } if ( self.bot.isfrozen || level.gameEnded || !gameFlag( "prematch_done" ) ) + { continue; + } if ( self.bot.isfraggingafter || self.bot.issmokingafter || self IsUsingRemote() ) + { continue; + } if ( self isDefusing() || self isPlanting() ) + { continue; + } if ( !getDvarInt( "bots_play_nade" ) ) + { continue; + } self grenade_danager_loop(); } @@ -716,16 +790,24 @@ stance_loop() toStance = "stand"; if ( self.bot.next_wp != -1 ) + { toStance = level.waypoints[self.bot.next_wp].type; + } if ( !isDefined( toStance ) ) + { toStance = "crouch"; + } if ( toStance == "stand" && randomInt( 100 ) <= self.pers["bots"]["behavior"]["crouch"] ) + { toStance = "crouch"; + } if ( self.hasRiotShieldEquipped && isDefined( self.bot.target ) && isDefined( self.bot.target.entity ) && isPlayer( self.bot.target.entity ) ) + { toStance = "crouch"; + } if ( toStance == "climb" ) { @@ -734,37 +816,59 @@ stance_loop() } if ( toStance != "stand" && toStance != "crouch" && toStance != "prone" ) + { toStance = "crouch"; + } if ( toStance == "stand" ) + { self stand(); + } else if ( toStance == "crouch" ) + { self crouch(); + } else + { self prone(); + } chance = self.pers["bots"]["behavior"]["sprint"]; if ( getTime() - 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( self getCurrentWeapon() ) && self isInRange( self.bot.target.dist, self getCurrentWeapon() ) ) + { return; + } if ( self.bot.sprintendtime != -1 && getTime() - 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(); @@ -803,7 +907,9 @@ stance() self.bot.climbing = false; if ( self.bot.isfrozen || self IsUsingRemote() ) + { continue; + } self stance_loop(); } @@ -836,24 +942,34 @@ reload_thread() wait 2.5; if ( self.bot.isfrozen || level.gameEnded || !gameFlag( "prematch_done" ) ) + { return; + } 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 ) || self IsUsingRemote() ) + { return; + } maxsize = WeaponClipSize( cur ); cursize = self GetWeaponammoclip( cur ); if ( cursize / maxsize < 0.5 ) + { self thread reload(); + } } /* @@ -872,10 +988,14 @@ updateBones() self waittill_any_timeout( waittime, "new_enemy" ); if ( !isAlive( self ) ) + { return; + } if ( !isDefined( self.bot.target ) ) + { continue; + } self.bot.target.bone = random( bones ); } @@ -914,20 +1034,28 @@ updateAimOffset( obj, theTime ) offsetAmount = self.pers["bots"]["skill"]["aim_offset_amount"]; if ( offsetAmount > 0 ) + { obj.aim_offset_base = ( randomFloatRange( 0 - offsetAmount, offsetAmount ), randomFloatRange( 0 - offsetAmount, offsetAmount ), randomFloatRange( 0 - offsetAmount, offsetAmount ) ); + } 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; } @@ -950,9 +1078,13 @@ targetObjUpdateTraced( obj, daDist, ent, theTime, isScriptObj, usingRemote ) if ( !usingRemote && !isScriptObj ) { if ( daDist > distMax ) + { timeMulti = 0; + } else if ( daDist > distClose ) + { timeMulti = 1 - ( ( daDist - distClose ) / ( distMax - distClose ) ); + } } obj.no_trace_time = 0; @@ -997,10 +1129,14 @@ target_loop() if ( usingRemote ) { if ( isDefined( level.ac130player ) && level.ac130player == self ) + { vehEnt = level.ac130.planeModel; + } if ( isDefined( level.chopper ) && isDefined( level.chopper.gunner ) && level.chopper.gunner == self ) + { vehEnt = level.chopper; + } } // reduce fov if ads'ing @@ -1024,7 +1160,9 @@ target_loop() if ( i == -1 ) { if ( !isDefined( self.bot.script_target ) ) + { continue; + } ent = self.bot.script_target; key = ent getEntityNumber() + ""; @@ -1034,7 +1172,9 @@ target_loop() entOrigin = ent.origin; if ( isDefined( self.bot.script_target_offset ) ) + { entOrigin += self.bot.script_target_offset; + } if ( ignoreSmoke || ( SmokeTrace( myEye, entOrigin, level.smokeRadius ) ) && bulletTracePassed( myEye, entOrigin, false, ent ) ) { @@ -1051,7 +1191,9 @@ target_loop() else { if ( !isObjDef ) + { continue; + } self targetObjUpdateNoTrace( obj ); @@ -1067,7 +1209,9 @@ target_loop() player = level.players[i]; if ( player == self ) + { continue; + } key = player getEntityNumber() + ""; obj = self.bot.targets[key]; @@ -1075,14 +1219,18 @@ target_loop() daDist = distanceSquared( self.origin, player.origin ); if ( usingRemote ) + { daDist = 0; + } isObjDef = isDefined( obj ); if ( ( level.teamBased && self.team == player.team ) || player.sessionstate != "playing" || !isReallyAlive( player ) ) { if ( isObjDef ) + { self.bot.targets[key] = undefined; + } continue; } @@ -1141,7 +1289,9 @@ target_loop() else { if ( !isObjDef ) + { continue; + } self targetObjUpdateNoTrace( obj ); @@ -1154,10 +1304,14 @@ target_loop() } if ( !isdefined( obj ) ) + { continue; + } if ( theTime - obj.time < initReactTime ) + { continue; + } timeDiff = theTime - obj.trace_time_time; @@ -1168,11 +1322,15 @@ target_loop() } if ( timeDiff == bestTime ) + { bestTargets[key] = obj; + } } if ( hasTarget && isDefined( bestTargets[self.bot.target.entity getEntityNumber() + ""] ) ) + { return; + } closest = 2147483647; toBeTarget = undefined; @@ -1184,7 +1342,9 @@ target_loop() theDist = bestTargets[bestKeys[i]].dist; if ( theDist > closest ) + { continue; + } closest = theDist; toBeTarget = bestTargets[bestKeys[i]]; @@ -1194,10 +1354,14 @@ target_loop() 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 ) { @@ -1219,10 +1383,14 @@ target() wait 0.05; if ( !isAlive( self ) ) + { return; + } if ( self maps\mp\_flashgrenades::isFlashbanged() ) + { continue; + } self target_loop(); } @@ -1241,13 +1409,19 @@ onNewEnemy() self waittill( "new_enemy" ); if ( !isDefined( self.bot.target ) ) + { continue; + } if ( !isDefined( self.bot.target.entity ) || !isPlayer( self.bot.target.entity ) ) + { continue; + } if ( self.bot.target.didlook ) + { continue; + } self thread watchToLook(); } @@ -1265,47 +1439,73 @@ watchToLook() 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 thread jump(); @@ -1313,7 +1513,9 @@ watchToLook() 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(); @@ -1360,7 +1562,9 @@ aim_loop() aimspeed = self.pers["bots"]["skill"]["aim_time"]; if ( self IsStunned() || self isArtShocked() ) + { aimspeed = 1; + } usingRemote = self IsUsingRemote(); curweap = self getCurrentWeapon(); @@ -1383,7 +1587,9 @@ aim_loop() self thread pressAds(); if ( curweap == "javelin_mp" && getDvarInt( "bots_play_fire" ) ) + { self botFire( curweap ); + } return; } @@ -1404,12 +1610,16 @@ aim_loop() 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; @@ -1420,16 +1630,24 @@ aim_loop() 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" || curweap == "throwingknife_mp" ) ) { if ( 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 ) ) @@ -1448,12 +1666,18 @@ aim_loop() time = 0.5; if ( nade == "frag_grenade_mp" ) + { time = 2; + } if ( isSecondaryGrenade( nade ) ) + { self thread smoke( time ); + } else + { self thread frag( time ); + } self notify( "kill_goal" ); } @@ -1465,14 +1689,20 @@ aim_loop() 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(); + } } } if ( !usingRemote ) + { self thread bot_lookat( last_pos + ( 0, 0, self GetPlayerViewHeight() + nadeAimOffset ), aimspeed ); + } else + { self thread bot_lookat( last_pos, aimspeed ); + } return; } @@ -1489,11 +1719,17 @@ aim_loop() 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 getVelocity(), true ); + } } else { @@ -1505,15 +1741,21 @@ aim_loop() 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 ); + } } knifeDist = level.bots_maxKnifeDistance; if ( self _hasPerk( "specialty_extendedmelee" ) ) + { knifeDist *= 1.995; + } if ( ( isplay || target.classname == "misc_turret" ) && !self.bot.isknifingafter && conedot > 0.9 && dist < knifeDist && trace_time > reaction_time && !usingRemote && getDvarInt( "bots_play_knife" ) ) { @@ -1523,7 +1765,9 @@ aim_loop() } if ( !self canFire( curweap ) || !self isInRange( dist, curweap ) ) + { return; + } canADS = ( self canAds( dist, curweap ) && conedot > 0.75 ); @@ -1534,25 +1778,37 @@ aim_loop() 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 ( curweap == "at4_mp" && entIsVehicle( self.bot.target.entity ) && ( !IsDefined( self.stingerStage ) || self.stingerStage != 2 ) ) + { return; + } 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( curweap ); + } if ( isplay ) + { self thread start_bot_after_target( target ); + } } return; @@ -1567,26 +1823,36 @@ aim_loop() dist = DistanceSquared( self.origin, last_pos ); if ( self.bot.isfraggingafter || self.bot.issmokingafter ) + { nadeAimOffset = dist / 3000; + } else if ( curweap != "none" && ( weaponClass( curweap ) == "grenade" || curweap == "throwingknife_mp" ) ) { if ( getWeaponClass( curweap ) == "weapon_projectile" ) + { nadeAimOffset = dist / 16000; + } else + { nadeAimOffset = dist / 3000; + } } aimpos = last_pos + ( 0, 0, self GetPlayerViewHeight() + nadeAimOffset ); if ( usingRemote ) + { aimpos = last_pos; + } 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 ); @@ -1597,17 +1863,25 @@ aim_loop() 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( curweap ); + } return; } @@ -1627,12 +1901,18 @@ aim_loop() 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 ); + } } } @@ -1649,10 +1929,14 @@ aim() wait 0.05; if ( !isAlive( self ) ) + { return; + } if ( !gameFlag( "prematch_done" ) || level.gameEnded || self.bot.isfrozen || self maps\mp\_flashgrenades::isFlashbanged() ) + { continue; + } self aim_loop(); } @@ -1671,17 +1955,23 @@ botFire( curweap ) if ( self.bot.is_cur_akimbo ) self thread pressAds(); - return; + { + return; + } } if ( self.bot.semi_time ) + { return; + } self thread pressFire(); if ( self.bot.is_cur_akimbo ) self thread pressAds(); - self thread doSemiTime(); + { + self thread doSemiTime(); + } } /* @@ -1705,13 +1995,19 @@ doSemiTime() canFire( curweap ) { if ( curweap == "none" ) + { return false; + } if ( curweap == "riotshield_mp" || curweap == "onemanarmy_mp" ) + { return false; + } if ( self IsUsingRemote() ) + { return true; + } return self GetWeaponammoclip( curweap ); } @@ -1722,35 +2018,53 @@ canFire( curweap ) canAds( dist, curweap ) { if ( self IsUsingRemote() ) + { return false; + } if ( curweap == "none" ) + { return false; + } if ( curweap == "c4_mp" ) + { return RandomInt( 2 ); + } 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; + } if ( curweap == "riotshield_mp" || curweap == "onemanarmy_mp" ) + { return false; + } if ( self.bot.is_cur_akimbo ) + { return false; + } return true; } @@ -1761,18 +2075,26 @@ canAds( dist, curweap ) isInRange( dist, curweap ) { if ( curweap == "none" ) + { return false; + } weapclass = weaponClass( curweap ); if ( self IsUsingRemote() ) + { return true; + } if ( ( weapclass == "spread" || self.bot.is_cur_akimbo ) && dist > level.bots_maxShotgunDistance ) + { return false; + } if ( curweap == "riotshield_mp" && dist > level.bots_maxKnifeDistance ) + { return false; + } return true; } @@ -1830,10 +2152,14 @@ walk_loop() if ( isPlayer( 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; } @@ -1842,7 +2168,9 @@ walk_loop() dist = 16; if ( level.waypointCount ) + { goal = level.waypoints[randomInt( level.waypointCount )].origin; + } else { self thread killWalkCauseNoWaypoints(); @@ -1893,7 +2221,9 @@ walk_loop() else { if ( hasTarget ) + { goal = self.bot.target.last_seen_pos; + } self notify( "new_goal_internal" ); } @@ -1919,13 +2249,19 @@ walk() self botSetMoveTo( self.origin ); if ( !getDVarINt( "bots_play_move" ) ) + { continue; + } if ( level.gameEnded || !gameFlag( "prematch_done" ) || self.bot.isfrozen || self.bot.stop_move ) + { continue; + } if ( self IsUsingRemote() ) + { continue; + } if ( self maps\mp\_flashgrenades::isFlashbanged() ) { @@ -1961,7 +2297,9 @@ strafe( target ) strafe = traceLeft["position"]; if ( traceRight["fraction"] > traceLeft["fraction"] ) + { strafe = traceRight["position"]; + } self.bot.last_next_wp = -1; self.bot.last_second_next_wp = -1; @@ -1980,7 +2318,9 @@ watchOnGoal( goal, dis ) self endon( "kill_goal" ); while ( DistanceSquared( self.origin, goal ) > dis ) + { wait 0.05; + } self notify( "goal_internal" ); } @@ -1993,7 +2333,9 @@ cleanUpAStar( team ) self waittill_any( "death", "disconnect", "kill_goal" ); for ( i = self.bot.astar.size - 1; i >= 0; i-- ) + { RemoveWaypointUsage( self.bot.astar[i], team ); + } } /* @@ -2004,12 +2346,16 @@ initAStar( goal ) team = undefined; if ( level.teamBased ) + { team = self.team; + } self.bot.astar = AStarSearch( self.origin, goal, team, self.bot.greedy_path ); if ( isDefined( team ) ) + { self thread cleanUpAStar( team ); + } return self.bot.astar.size - 1; } @@ -2022,7 +2368,9 @@ removeAStar() remove = self.bot.astar.size - 1; if ( level.teamBased ) + { RemoveWaypointUsage( self.bot.astar[remove], self.team ); + } self.bot.astar[remove] = undefined; @@ -2055,9 +2403,13 @@ doWalkScriptNotify() self endon( "kill_goal" ); if ( self waittill_either_return( "goal_internal", "bad_path_internal" ) == "goal_internal" ) + { self notify( "goal" ); + } else + { self notify( "bad_path" ); + } } /* @@ -2072,7 +2424,9 @@ doWalk( goal, dist, isScriptGoal ) dist *= dist; if ( isScriptGoal ) + { self thread doWalkScriptNotify(); + } self thread killWalkOnEvents(); self thread watchOnGoal( goal, dist ); @@ -2081,7 +2435,9 @@ doWalk( goal, dist, isScriptGoal ) // 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 ) { @@ -2094,7 +2450,9 @@ doWalk( goal, dist, isScriptGoal ) self.bot.second_next_wp = -1; if ( current > 0 ) + { self.bot.second_next_wp = self.bot.astar[current - 1]; + } self notify( "new_static_waypoint" ); @@ -2123,7 +2481,9 @@ doWalk( goal, dist, isScriptGoal ) wait 1; if ( DistanceSquared( self.origin, goal ) > dist ) + { self notify( "bad_path_internal" ); + } } /* @@ -2132,7 +2492,9 @@ doWalk( goal, dist, isScriptGoal ) movetowards( goal ) { if ( !isDefined( goal ) ) + { return; + } self.bot.towards_goal = goal; @@ -2142,9 +2504,13 @@ movetowards( goal ) time = 0; if ( self.bot.issprinting ) + { tempGoalDist = level.bots_goalDistance * 2; + } else + { tempGoalDist = level.bots_goalDistance; + } while ( distanceSquared( self.origin, goal ) > tempGoalDist ) { @@ -2182,7 +2548,9 @@ movetowards( goal ) else if ( time == 2000 ) { if ( distanceSquared( self.origin, lastOri ) < 32 * 32 ) + { self crouch(); + } } else if ( time == 1750 ) { @@ -2200,17 +2568,27 @@ movetowards( goal ) 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; @@ -2272,9 +2650,13 @@ getRandomLargestStafe( dist ) holdbreath( what ) { if ( what ) + { self BotBuiltinBotAction( "+holdbreath" ); + } else + { self BotBuiltinBotAction( "-holdbreath" ); + } } /* @@ -2387,14 +2769,18 @@ frag( time ) 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; @@ -2414,14 +2800,18 @@ smoke( time ) 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; @@ -2441,12 +2831,16 @@ use( time ) self endon( "bot_use" ); if ( !isDefined( time ) ) + { time = 0.05; + } self BotBuiltinBotAction( "+activate" ); if ( time ) + { wait time; + } self BotBuiltinBotAction( "-activate" ); } @@ -2459,9 +2853,13 @@ fire( what ) self notify( "bot_fire" ); if ( what ) + { self BotBuiltinBotAction( "+fire" ); + } else + { self BotBuiltinBotAction( "-fire" ); + } } /* @@ -2475,12 +2873,16 @@ pressFire( time ) self endon( "bot_fire" ); if ( !isDefined( time ) ) + { time = 0.05; + } self BotBuiltinBotAction( "+fire" ); if ( time ) + { wait time; + } self BotBuiltinBotAction( "-fire" ); } @@ -2493,9 +2895,13 @@ ads( what ) self notify( "bot_ads" ); if ( what ) + { self BotBuiltinBotAction( "+ads" ); + } else + { self BotBuiltinBotAction( "-ads" ); + } } /* @@ -2509,12 +2915,16 @@ pressADS( time ) self endon( "bot_ads" ); if ( !isDefined( time ) ) + { time = 0.05; + } self BotBuiltinBotAction( "+ads" ); if ( time ) + { wait time; + } self BotBuiltinBotAction( "-ads" ); } @@ -2530,7 +2940,9 @@ jump() self endon( "bot_jump" ); if ( self IsUsingRemote() ) + { return; + } if ( self getStance() != "stand" ) { @@ -2549,7 +2961,9 @@ jump() stand() { if ( self IsUsingRemote() ) + { return; + } self BotBuiltinBotAction( "-gocrouch" ); self BotBuiltinBotAction( "-goprone" ); @@ -2561,7 +2975,9 @@ stand() crouch() { if ( self IsUsingRemote() ) + { return; + } self BotBuiltinBotAction( "+gocrouch" ); self BotBuiltinBotAction( "-goprone" ); @@ -2573,7 +2989,9 @@ crouch() prone() { if ( self IsUsingRemote() || self.hasRiotShieldEquipped ) + { return; + } self BotBuiltinBotAction( "-gocrouch" ); self BotBuiltinBotAction( "+goprone" ); @@ -2603,9 +3021,13 @@ botGetThirdPersonOffset( angles ) curweap = self getCurrentWeapon(); if ( ( isSubStr( curweap, "thermal_" ) || weaponClass( curweap ) == "sniper" ) && !isSubStr( curweap, "acog_" ) ) + { offset = ( 0, 0, 0 ); + } else + { offset = getDvarVector( "camera_thirdPersonOffsetAds" ); + } } // rotate about x // y cos xangle - z sin xangle // y sin xangle + z cos xangle @@ -2634,24 +3056,36 @@ bot_lookat( pos, time, vel, doAimPredict ) level endon ( "game_ended" ); if ( level.gameEnded || !gameFlag( "prematch_done" ) || 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; + } myAngle = self getPlayerAngles(); diff --git a/maps/mp/bots/_bot_script.gsc b/maps/mp/bots/_bot_script.gsc index e113ee6..3bb0353 100644 --- a/maps/mp/bots/_bot_script.gsc +++ b/maps/mp/bots/_bot_script.gsc @@ -75,10 +75,14 @@ bot_get_prestige() player = level.players[i]; if ( !isDefined( player.team ) ) + { continue; + } if ( player is_bot() ) + { continue; + } p = player getPlayerData( "prestige" ); break; @@ -115,10 +119,14 @@ bot_get_rank() player = level.players[i]; if ( player == self ) + { continue; + } if ( !IsDefined( player.pers[ "rank" ] ) ) + { continue; + } if ( player is_bot() ) { @@ -131,7 +139,9 @@ bot_get_rank() } if ( !human_ranks.size ) + { human_ranks[ human_ranks.size ] = Round( random_normal_distribution( 45, 20, 0, level.maxRank ) ); + } human_avg = array_average( human_ranks ); @@ -173,10 +183,14 @@ getCardTitles() card_name = tableLookupByRow( "mp/cardTitleTable.csv", i, 0 ); if ( card_name == "" ) + { continue; + } if ( !isSubStr( card_name, "cardtitle_" ) ) + { continue; + } cards[cards.size] = card_name; } @@ -196,10 +210,14 @@ getCardIcons() card_name = tableLookupByRow( "mp/cardIconTable.csv", i, 0 ); if ( card_name == "" ) + { continue; + } if ( !isSubStr( card_name, "cardicon_" ) ) + { continue; + } cards[cards.size] = card_name; } @@ -215,7 +233,9 @@ isValidAttachmentCombo( att1, att2 ) colIndex = tableLookupRowNum( "mp/attachmentCombos.csv", 0, att1 ); if ( tableLookup( "mp/attachmentCombos.csv", 0, att2, colIndex ) == "no" ) + { return false; + } return true; } @@ -257,7 +277,9 @@ getPrimaries() weapon_type = tableLookupByRow( "mp/statstable.csv", i, 2 ); if ( weapon_type != "weapon_assault" && weapon_type != "weapon_riot" && weapon_type != "weapon_smg" && weapon_type != "weapon_sniper" && weapon_type != "weapon_lmg" ) + { continue; + } weapon_name = tableLookupByRow( "mp/statstable.csv", i, 4 ); @@ -279,12 +301,16 @@ getSecondaries() weapon_type = tableLookupByRow( "mp/statstable.csv", i, 2 ); if ( weapon_type != "weapon_pistol" && weapon_type != "weapon_machine_pistol" && weapon_type != "weapon_projectile" && weapon_type != "weapon_shotgun" ) + { continue; + } weapon_name = tableLookupByRow( "mp/statstable.csv", i, 4 ); if ( weapon_name == "gl" ) + { continue; + } secondaries[secondaries.size] = weapon_name; } @@ -304,7 +330,9 @@ getCamos() camo_name = tableLookupByRow( "mp/camoTable.csv", i, 1 ); if ( camo_name == "" ) + { continue; + } camos[camos.size] = camo_name; } @@ -324,15 +352,21 @@ getPerks( perktype ) perk_type = tableLookupByRow( "mp/perktable.csv", i, 5 ); if ( perk_type != perktype ) + { continue; + } perk_name = tableLookupByRow( "mp/perktable.csv", i, 1 ); if ( perk_name == "specialty_c4death" ) + { continue; + } if ( perk_name == "_specialty_blastshield" ) + { continue; + } perks[perks.size] = perk_name; } @@ -360,16 +394,24 @@ getKillstreaks() streak_name = tableLookupByRow( "mp/killstreakTable.csv", i, 1 ); if ( streak_name == "" || streak_name == "none" ) + { continue; + } if ( streak_name == "b1" ) + { continue; + } if ( streak_name == "sentry" ) // theres an airdrop version + { continue; + } if ( isSubstr( streak_name, "KILLSTREAKS_" ) ) + { continue; + } killstreaks[killstreaks.size] = streak_name; } @@ -394,44 +436,66 @@ chooseRandomPerk( perkkind, primary, primaryAtts ) if ( !allowOp ) { if ( perkkind == "perk4" ) + { return "specialty_null"; + } if ( perk == "specialty_pistoldeath" ) + { continue; + } if ( perk == "specialty_coldblooded" ) + { continue; + } if ( perk == "specialty_localjammer" ) + { continue; + } } if ( reasonable ) { if ( perk == "specialty_bling" ) + { continue; + } if ( perk == "specialty_localjammer" ) + { continue; + } if ( perk == "throwingknife_mp" ) + { continue; + } if ( perk == "specialty_blastshield" ) + { continue; + } if ( perk == "frag_grenade_mp" ) + { continue; + } if ( perk == "specialty_copycat" ) + { continue; + } if ( perkkind == "perk1" ) { if ( perk == "specialty_onemanarmy" ) { if ( primaryAtts[0] != "gl"/* && primaryAtts[1] != "gl"*/ ) + { continue; + } } } @@ -442,61 +506,95 @@ chooseRandomPerk( perkkind, primary, primaryAtts ) if ( perk == "specialty_explosivedamage" ) { if ( primaryAtts[0] != "gl"/* && primaryAtts[1] != "gl"*/ ) + { continue; + } } else { if ( randomInt( 100 ) < 10 ) + { continue; + } if ( primary == "cheytac" ) + { continue; + } if ( primary == "rpd" ) + { continue; + } if ( primary == "ak47" && randomInt( 100 ) < 80 ) + { continue; + } if ( primary == "aug" ) + { continue; + } if ( primary == "barrett" && randomInt( 100 ) < 80 ) + { continue; + } if ( primary == "tavor" && randomInt( 100 ) < 80 ) + { continue; + } if ( primary == "scar" ) + { continue; + } if ( primary == "masada" && randomInt( 100 ) < 60 ) + { continue; + } if ( primary == "m4" && randomInt( 100 ) < 80 ) + { continue; + } if ( primary == "m16" ) + { continue; + } if ( primary == "fal" ) + { continue; + } if ( primary == "famas" ) + { continue; + } } } } } if ( perk == "specialty_null" ) + { continue; + } if ( !self isItemUnlocked( perk ) ) + { continue; + } if ( RandomFloatRange( 0, 1 ) < ( ( rank / level.maxRank ) + 0.1 ) ) + { self.pers["bots"]["unlocks"]["upgraded_" + perk] = true; + } return perk; } @@ -514,7 +612,9 @@ chooseRandomCamo() camo = random( camos ); if ( camo == "gold" || camo == "prestige" ) + { continue; + } return camo; } @@ -536,35 +636,53 @@ chooseRandomPrimary() if ( !allowOp ) { if ( primary == "riotshield" ) + { continue; + } } if ( reasonable ) { if ( primary == "riotshield" ) + { continue; + } if ( primary == "wa2000" ) + { continue; + } if ( primary == "uzi" ) + { continue; + } if ( primary == "sa80" ) + { continue; + } if ( primary == "fn2000" ) + { continue; + } if ( primary == "m240" ) + { continue; + } if ( primary == "mg4" ) + { continue; + } } if ( !self isItemUnlocked( primary ) ) + { continue; + } return primary; } @@ -576,7 +694,9 @@ chooseRandomPrimary() chooseRandomSecondary( perk1 ) { if ( perk1 == "specialty_onemanarmy" ) + { return "onemanarmy"; + } secondaries = getSecondaries(); allowOp = ( getDvarInt( "bots_loadout_allow_op" ) >= 1 ); @@ -589,23 +709,33 @@ chooseRandomSecondary( perk1 ) if ( !allowOp ) { if ( secondary == "at4" || secondary == "rpg" || secondary == "m79" ) + { continue; + } } if ( reasonable ) { if ( secondary == "ranger" ) + { continue; + } if ( secondary == "model1887" ) + { continue; + } } if ( !self isItemUnlocked( secondary ) ) + { continue; + } if ( secondary == "onemanarmy" ) + { continue; + } return secondary; } @@ -636,38 +766,54 @@ chooseRandomAttachmentComboForGun( gun ) att2 = random( atts ); if ( !isValidAttachmentCombo( att1, att2 ) ) + { continue; + } if ( !allowOp ) { if ( att1 == "gl" || att2 == "gl" ) + { continue; + } } if ( reasonable ) { if ( att1 == "shotgun" || att2 == "shotgun" ) + { continue; + } if ( att1 == "akimbo" || att2 == "akimbo" ) { if ( gun != "ranger" && gun != "model1887" && gun != "glock" ) + { continue; + } } if ( att1 == "acog" || att2 == "acog" ) + { continue; + } if ( att1 == "thermal" || att2 == "thermal" ) + { continue; + } if ( att1 == "rof" || att2 == "rof" ) + { continue; + } if ( att1 == "silencer" || att2 == "silencer" ) { if ( gun == "spas12" || gun == "aa12" || gun == "striker" || gun == "rpd" || gun == "m1014" || gun == "cheytac" || gun == "barrett" || gun == "aug" || gun == "m240" || gun == "mg4" || gun == "sa80" || gun == "wa2000" ) + { continue; + } } } @@ -694,7 +840,9 @@ chooseRandomTactical() if ( reasonable ) { if ( tact == "smoke_grenade" ) + { continue; + } } return tact; @@ -709,7 +857,9 @@ setClasses() n = 5; if ( !self is_bot() ) + { n = 15; + } rank = self maps\mp\gametypes\_rank::getRankForXp( self getPlayerData( "experience" ) ); @@ -730,7 +880,9 @@ setClasses() perk1 = chooseRandomPerk( "perk1", primary, primaryAtts ); if ( perk1 != "specialty_bling" ) + { primaryAtts[1] = "none"; + } perk2 = chooseRandomPerk( "perk2", primary, primaryAtts ); primaryCamo = chooseRandomCamo(); @@ -738,7 +890,9 @@ setClasses() secondaryAtts = chooseRandomAttachmentComboForGun( secondary ); if ( perk1 != "specialty_bling" || !isDefined( self.pers["bots"]["unlocks"]["upgraded_specialty_bling"] ) ) + { secondaryAtts[1] = "none"; + } if ( !getDvarInt( "developer_script" ) ) { @@ -773,18 +927,26 @@ isColidingKillstreak( killstreaks, killstreak ) ks = killstreaks[i]; if ( ks == "" ) + { continue; + } if ( ks == "none" ) + { continue; + } ksV = getKillsNeededForStreak( ks ); if ( ksV <= 0 ) + { continue; + } if ( ksV != ksVal ) + { continue; + } return true; } @@ -809,13 +971,19 @@ setKillstreaks() chooseableStreaks = 0; if ( rankId >= 10 ) + { chooseableStreaks++; + } if ( rankId >= 15 ) + { chooseableStreaks++; + } if ( rankId >= 22 ) + { chooseableStreaks++; + } reasonable = getDvarInt( "bots_loadout_reasonable" ); op = getDvarInt( "bots_loadout_allow_op" ); @@ -827,41 +995,61 @@ setKillstreaks() slot = randomInt( 3 ); if ( killstreaks[slot] != "" ) + { continue; + } streak = random( allStreaks ); if ( isColidingKillstreak( killstreaks, streak ) ) + { continue; + } if ( reasonable ) { if ( streak == "stealth_airstrike" ) + { continue; + } if ( streak == "airdrop_mega" ) + { continue; + } if ( streak == "emp" ) + { continue; + } if ( streak == "airdrop_sentry_minigun" ) + { continue; + } if ( streak == "airdrop" ) + { continue; + } if ( streak == "precision_airstrike" ) + { continue; + } if ( streak == "helicopter" ) + { continue; + } } if ( op ) { if ( streak == "nuke" ) + { continue; + } } killstreaks[slot] = streak; @@ -869,13 +1057,19 @@ setKillstreaks() } if ( killstreaks[0] == "" ) + { killstreaks[0] = "uav"; + } if ( killstreaks[1] == "" ) + { killstreaks[1] = "airdrop"; + } if ( killstreaks[2] == "" ) + { killstreaks[2] = "predator_missile"; + } if ( !getDvarInt( "developer_script" ) ) { @@ -894,28 +1088,44 @@ onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, self.lastKiller = undefined; if ( !IsDefined( self ) || !isDefined( self.team ) ) + { 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 ( level.teamBased && eAttacker.team == self.team ) + { return; + } if ( !IsDefined( eInflictor ) || eInflictor.classname != "player" ) + { return; + } if ( !isAlive( eAttacker ) ) + { return; + } self.killerLocation = eAttacker.origin; self.lastKiller = eAttacker; @@ -927,34 +1137,54 @@ onKilled( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, onDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset ) { 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 ( level.teamBased && eAttacker.team == self.team ) + { return; + } if ( !IsDefined( eInflictor ) || eInflictor.classname != "player" ) + { return; + } if ( !isAlive( eAttacker ) ) + { return; + } if ( !isSubStr( sWeapon, "_silencer_" ) ) + { self bot_cry_for_help( eAttacker ); + } self SetAttacker( eAttacker ); } @@ -988,7 +1218,9 @@ bot_cry_for_help( attacker ) } if ( !isDefined( player.team ) ) + { continue; + } if ( !IsAlive( player ) ) { @@ -1054,7 +1286,9 @@ doKillcamStuff() wait 0.5 + randomInt( 3 ); if ( randomInt( 100 ) > 25 ) + { self notify( "use_copycat" ); + } wait 0.1; @@ -1073,17 +1307,23 @@ classWatch() for ( ;; ) { while ( !isdefined( self.pers["team"] ) || !allowClassChoiceUtil() ) + { wait .05; + } wait 0.5; if ( !isValidClass( self.class ) || !isDefined( self.bot_change_class ) ) + { self notify( "menuresponse", game["menu_changeclass"], self chooseRandomClass() ); + } self.bot_change_class = true; while ( isdefined( self.pers["team"] ) && isValidClass( self.class ) && isDefined( self.bot_change_class ) ) + { wait .05; + } } } @@ -1116,13 +1356,17 @@ chooseRandomClass() case 3: if ( rank >= 2 ) + { class = "class3"; + } break; case 4: if ( rank >= 3 ) + { class = "class4"; + } break; } @@ -1146,15 +1390,21 @@ teamWatch() for ( ;; ) { while ( !isdefined( self.pers["team"] ) || !allowTeamChoiceUtil() ) + { wait .05; + } wait 0.1; if ( self.team != "axis" && self.team != "allies" ) + { self notify( "menuresponse", game["menu_team"], getDvar( "bots_team" ) ); + } while ( isdefined( self.pers["team"] ) ) + { wait .05; + } } } @@ -1481,10 +1731,14 @@ onGiveLoadout_loop() class = self.class; if ( isDefined( self.bot_oma_class ) ) + { class = self.bot_oma_class; + } if ( allowClassChoiceUtil() ) + { self botGiveLoadout( self.team, class, !isDefined( self.bot_oma_class ) ); + } self.bot_oma_class = undefined; } @@ -1516,7 +1770,9 @@ onSpawned() self waittill( "spawned_player" ); if ( randomInt( 100 ) <= self.pers["bots"]["behavior"]["class"] ) + { self.bot_change_class = undefined; + } self.bot_lock_goal = false; self.bot_oma_class = undefined; @@ -1525,7 +1781,9 @@ onSpawned() self.bot_stuck_on_carepackage = undefined; if ( getDvarInt( "bots_play_obj" ) ) + { self thread bot_dom_cap_think(); + } } } @@ -1558,7 +1816,9 @@ start_bot_threads() // inventory usage if ( getDvarInt( "bots_play_killstreak" ) ) + { self thread bot_killstreak_think(); + } self thread bot_weapon_think(); self thread doReloadCancel(); @@ -1640,17 +1900,23 @@ bot_inc_bots( obj, unreach ) self endon( "bot_inc_bots" ); if ( !isDefined( obj ) ) + { return; + } if ( !isDefined( obj.bots ) ) + { obj.bots = 0; + } obj.bots++; ret = self waittill_any_return( "death", "disconnect", "bad_path", "goal", "new_goal" ); if ( isDefined( obj ) && ( ret != "bad_path" || !isDefined( unreach ) ) ) + { obj.bots--; + } } /* @@ -1698,10 +1964,14 @@ bot_escort_obj( obj, carrier ) wait 0.5; if ( !isDefined( obj ) ) + { break; + } if ( !isDefined( obj.carrier ) || carrier == obj.carrier ) + { break; + } } self notify( "goal" ); @@ -1723,10 +1993,14 @@ bot_get_obj( obj ) wait 0.5; if ( !isDefined( obj ) ) + { break; + } if ( isDefined( obj.carrier ) ) + { break; + } } self notify( "goal" ); @@ -1749,7 +2023,9 @@ bot_defend_site( site ) wait 0.5; if ( !site isInUse() ) + { break; + } } self notify( "bad_path" ); @@ -1772,16 +2048,24 @@ bot_go_plant( plant ) wait 1; if ( level.bombPlanted ) + { break; + } if ( self isTouching( plant.trigger ) ) + { break; + } } if ( level.bombPlanted ) + { self notify( "bad_path" ); + } else + { self notify( "goal" ); + } } /* @@ -1801,16 +2085,24 @@ bot_go_defuse( plant ) wait 1; if ( !level.bombPlanted ) + { break; + } if ( self isTouching( plant.trigger ) ) + { break; + } } if ( !level.bombPlanted ) + { self notify( "bad_path" ); + } else + { self notify( "goal" ); + } } /* @@ -1819,7 +2111,9 @@ bot_go_defuse( plant ) bot_wait_stop_move() { while ( !self isOnGround() || lengthSquared( self getVelocity() ) > 1 ) + { wait 0.25; + } } /* @@ -1849,12 +2143,16 @@ changeToWeapon( weap ) 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" ); @@ -1871,12 +2169,18 @@ botThrowGrenade( nade, time ) level endon( "game_ended" ); if ( !self GetAmmoCount( nade ) ) + { return false; + } if ( isSecondaryGrenade( nade ) ) + { self thread BotPressSmoke( time ); + } else + { self thread BotPressFrag( time ); + } ret = self waittill_any_timeout( 5, "grenade_fire" ); @@ -1891,8 +2195,12 @@ bot_array_nearest_curorigin( array ) result = undefined; for ( i = 0; i < array.size; i++ ) + { if ( !isDefined( result ) || DistanceSquared( self.origin, array[i].curorigin ) < DistanceSquared( self.origin, result.curorigin ) ) + { result = array[i]; + } + } return result; } @@ -1905,10 +2213,14 @@ getRocketAmmo() answer = self getLockonAmmo(); if ( isDefined( answer ) ) + { return answer; + } if ( self getAmmoCount( "rpg_mp" ) ) + { answer = "rpg_mp"; + } return answer; } @@ -1921,13 +2233,19 @@ getLockonAmmo() answer = undefined; if ( self getAmmoCount( "at4_mp" ) ) + { answer = "at4_mp"; + } if ( self getAmmoCount( "stinger_mp" ) ) + { answer = "stinger_mp"; + } if ( self getAmmoCount( "javelin_mp" ) ) + { answer = "javelin_mp"; + } return answer; } @@ -1956,10 +2274,14 @@ follow_target_loop() threat = self GetThreat(); if ( !isPlayer( threat ) ) + { return; + } if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["follow"] * 5 ) + { return; + } self BotNotifyBotEvent( "follow_threat", "start", threat ); @@ -1967,7 +2289,9 @@ follow_target_loop() self thread stop_go_target_on_death( threat ); if ( self waittill_any_return( "new_goal", "goal", "bad_path" ) != "new_goal" ) + { self ClearScriptGoal(); + } self BotNotifyBotEvent( "follow_threat", "stop", threat ); } @@ -1985,10 +2309,14 @@ follow_target() wait 1; if ( self HasScriptGoal() || self.bot_lock_goal ) + { continue; + } if ( !self HasThreat() ) + { continue; + } self follow_target_loop(); } @@ -2002,7 +2330,9 @@ bot_think_camp_loop() campSpot = getWaypointForIndex( random( self waypointsNear( getWaypointsOfType( "camp" ), 1024 ) ) ); if ( !isDefined( campSpot ) ) + { return; + } time = randomIntRange( 30, 90 ); @@ -2013,10 +2343,14 @@ bot_think_camp_loop() ret = self waittill_any_return( "new_goal", "goal", "bad_path" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } if ( ret != "goal" ) + { return; + } self BotNotifyBotEvent( "camp", "start", campSpot, time ); @@ -2039,10 +2373,14 @@ bot_think_camp() wait randomintrange( 4, 7 ); if ( self HasScriptGoal() || self.bot_lock_goal || self HasScriptAimPos() ) + { continue; + } if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["camp"] ) + { continue; + } self bot_think_camp_loop(); } @@ -2088,7 +2426,9 @@ killCampAfterEntGone( ent ) wait 0.05; if ( !isDefined( ent ) ) + { break; + } } self ClearScriptGoal(); @@ -2130,16 +2470,24 @@ bot_think_follow_loop() player = level.players[i]; if ( player == self ) + { continue; + } if ( !isReallyAlive( player ) ) + { continue; + } if ( player.team != self.team ) + { continue; + } if ( DistanceSquared( player.origin, self.origin ) > distSq ) + { continue; + } follows[follows.size] = player; } @@ -2147,7 +2495,9 @@ bot_think_follow_loop() toFollow = random( follows ); if ( !isDefined( toFollow ) ) + { return; + } time = randomIntRange( 10, 20 ); @@ -2172,13 +2522,19 @@ bot_think_follow() wait randomIntRange( 3, 5 ); if ( self HasScriptGoal() || self.bot_lock_goal || self HasScriptAimPos() ) + { continue; + } if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["follow"] ) + { continue; + } if ( !level.teamBased ) + { continue; + } self bot_think_follow_loop(); } @@ -2198,7 +2554,9 @@ watchForFollowNewGoal() self waittill( "new_goal" ); if ( !isDefined( self.bot_was_follow_script_update ) ) + { break; + } } self ClearScriptAimPos(); @@ -2235,13 +2593,17 @@ followPlayer( who ) wait 0.05; if ( !isDefined( who ) || !isReallyAlive( who ) ) + { break; + } self SetScriptAimPos( who.origin + ( 0, 0, 42 ) ); myGoal = self GetScriptGoal(); if ( isDefined( myGoal ) && DistanceSquared( myGoal, who.origin ) < 64 * 64 ) + { continue; + } self.bot_was_follow_script_update = true; self SetScriptGoal( who.origin, 32 ); @@ -2267,14 +2629,18 @@ bot_perk_think_loop() if ( !self _hasPerk( "_specialty_blastshield" ) ) { if ( randomInt( 100 ) < 65 ) + { break; + } self _setPerk( "_specialty_blastshield" ); } else { if ( randomInt( 100 ) < 90 ) + { break; + } self _unsetPerk( "_specialty_blastshield" ); } @@ -2285,10 +2651,14 @@ bot_perk_think_loop() for ( ; self _hasPerk( "specialty_onemanarmy" ) && self hasWeapon( "onemanarmy_mp" ); ) { if ( self HasThreat() || self HasBotJavelinLocation() ) + { break; + } if ( self InLastStand() && !self InFinalStand() ) + { break; + } anyWeapout = false; weaponsList = self GetWeaponsListAll(); @@ -2298,15 +2668,20 @@ bot_perk_think_loop() weap = weaponsList[i]; if ( self getAmmoCount( weap ) || weap == "onemanarmy_mp" ) + { continue; + } anyWeapout = true; } if ( ( !anyWeapout && randomInt( 100 ) < 90 ) || randomInt( 100 ) < 10 ) + { break; + } class = self chooseRandomClass(); + self.bot_oma_class = class; if ( !self changeToWeapon( "onemanarmy_mp" ) ) @@ -2340,13 +2715,19 @@ bot_perk_think() wait randomIntRange( 5, 7 ); if ( self IsUsingRemote() ) + { continue; + } if ( self BotIsFrozen() ) + { continue; + } if ( self isDefusing() || self isPlanting() ) + { continue; + } self bot_perk_think_loop(); } @@ -2358,7 +2739,9 @@ bot_perk_think() bot_use_tube_think_loop( data ) { if ( data.doFastContinue ) + { data.doFastContinue = false; + } else { wait randomintRange( 3, 7 ); @@ -2366,34 +2749,52 @@ bot_use_tube_think_loop( data ) chance = self.pers["bots"]["behavior"]["nade"] / 2; if ( chance > 20 ) + { chance = 20; + } if ( randomInt( 100 ) > chance ) + { return; + } } tube = self getValidTube(); if ( !isDefined( tube ) ) + { return; + } if ( self HasThreat() || self HasBotJavelinLocation() || self HasScriptAimPos() ) + { return; + } if ( self BotIsFrozen() ) + { return; + } if ( self IsBotFragging() || self IsBotSmoking() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self InLastStand() && !self InFinalStand() ) + { return; + } loc = undefined; @@ -2411,13 +2812,19 @@ bot_use_tube_think_loop( data ) dist = DistanceSquared( self.origin, loc ); if ( dist < level.bots_minGrenadeDistance || dist > level.bots_maxGrenadeDistance * 5 ) + { return; + } if ( !bulletTracePassed( self.origin + ( 0, 0, 5 ), self.origin + ( 0, 0, 2048 ), false, self ) ) + { return; + } if ( !bulletTracePassed( loc + ( 0, 0, 5 ), loc + ( 0, 0, 2048 ), false, self ) ) + { return; + } loc += ( 0, 0, dist / 16000 ); } @@ -2430,10 +2837,14 @@ bot_use_tube_think_loop( data ) ret = self waittill_any_return( "new_goal", "goal", "bad_path" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } if ( ret != "goal" ) + { return; + } data.doFastContinue = true; return; @@ -2446,7 +2857,9 @@ bot_use_tube_think_loop( data ) } if ( !isDefined( loc ) ) + { return; + } self BotNotifyBotEvent( "tube", "start", loc, tube ); @@ -2489,7 +2902,9 @@ bot_use_tube_think() bot_use_equipment_think_loop( data ) { if ( data.doFastContinue ) + { data.doFastContinue = false; + } else { wait randomintRange( 2, 4 ); @@ -2497,43 +2912,67 @@ bot_use_equipment_think_loop( data ) chance = self.pers["bots"]["behavior"]["nade"] / 2; if ( chance > 20 ) + { chance = 20; + } if ( randomInt( 100 ) > chance ) + { return; + } } nade = undefined; if ( self GetAmmoCount( "claymore_mp" ) ) + { nade = "claymore_mp"; + } if ( self GetAmmoCount( "flare_mp" ) ) + { nade = "flare_mp"; + } if ( self GetAmmoCount( "c4_mp" ) ) + { nade = "c4_mp"; + } if ( !isDefined( nade ) ) + { return; + } if ( self HasThreat() || self HasBotJavelinLocation() || self HasScriptAimPos() ) + { return; + } if ( self BotIsFrozen() ) + { return; + } if ( self IsBotFragging() || self IsBotSmoking() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self inLastStand() && !self _hasPerk( "specialty_laststandoffhand" ) && !self inFinalStand() ) + { return; + } loc = undefined; @@ -2547,7 +2986,9 @@ bot_use_equipment_think_loop( data ) loc = myEye + AnglesToForward( self GetPlayerAngles() ) * 256; if ( !bulletTracePassed( myEye, loc, false, self ) ) + { return; + } } else { @@ -2558,10 +2999,14 @@ bot_use_equipment_think_loop( data ) ret = self waittill_any_return( "new_goal", "goal", "bad_path" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } if ( ret != "goal" ) + { return; + } data.doFastContinue = true; return; @@ -2574,7 +3019,9 @@ bot_use_equipment_think_loop( data ) } if ( !isDefined( loc ) ) + { return; + } self BotNotifyBotEvent( "equ", "start", loc, nade ); @@ -2612,7 +3059,9 @@ bot_use_equipment_think() bot_use_grenade_think_loop( data ) { if ( data.doFastContinue ) + { data.doFastContinue = false; + } else { wait randomintRange( 4, 7 ); @@ -2620,34 +3069,52 @@ bot_use_grenade_think_loop( data ) chance = self.pers["bots"]["behavior"]["nade"] / 2; if ( chance > 20 ) + { chance = 20; + } if ( randomInt( 100 ) > chance ) + { return; + } } nade = self getValidGrenade(); if ( !isDefined( nade ) ) + { return; + } if ( self HasThreat() || self HasBotJavelinLocation() || self HasScriptAimPos() ) + { return; + } if ( self BotIsFrozen() ) + { return; + } if ( self IsBotFragging() || self IsBotSmoking() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self inLastStand() && !self _hasPerk( "specialty_laststandoffhand" ) && !self inFinalStand() ) + { return; + } loc = undefined; @@ -2665,13 +3132,19 @@ bot_use_grenade_think_loop( data ) dist = DistanceSquared( self.origin, loc ); if ( dist < level.bots_minGrenadeDistance || dist > level.bots_maxGrenadeDistance ) + { return; + } if ( !bulletTracePassed( self.origin + ( 0, 0, 5 ), self.origin + ( 0, 0, 2048 ), false, self ) ) + { return; + } if ( !bulletTracePassed( loc + ( 0, 0, 5 ), loc + ( 0, 0, 2048 ), false, self ) ) + { return; + } loc += ( 0, 0, dist / 3000 ); } @@ -2684,10 +3157,14 @@ bot_use_grenade_think_loop( data ) ret = self waittill_any_return( "new_goal", "goal", "bad_path" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } if ( ret != "goal" ) + { return; + } data.doFastContinue = true; return; @@ -2700,7 +3177,9 @@ bot_use_grenade_think_loop( data ) } if ( !isDefined( loc ) ) + { return; + } self BotNotifyBotEvent( "nade", "start", loc, nade ); @@ -2711,7 +3190,9 @@ bot_use_grenade_think_loop( data ) time = 0.5; if ( nade == "frag_grenade_mp" ) + { time = 2; + } self botThrowGrenade( nade, time ); @@ -2747,20 +3228,30 @@ bot_watch_think_mw2_loop() if ( !isDefined( tube ) ) { if ( self GetAmmoCount( "at4_mp" ) ) + { tube = "at4_mp"; + } else if ( self GetAmmoCount( "rpg_mp" ) ) + { tube = "rpg_mp"; + } else + { return; + } } if ( self GetCurrentWeapon() == tube ) + { return; + } chance = self.pers["bots"]["behavior"]["nade"]; if ( randomInt( 100 ) > chance ) + { return; + } self thread ChangeToWeapon( tube ); } @@ -2779,19 +3270,29 @@ bot_watch_think_mw2() wait randomIntRange( 1, 4 ); if ( self BotIsFrozen() ) + { continue; + } if ( self isDefusing() || self isPlanting() ) + { continue; + } if ( self IsUsingRemote() ) + { continue; + } if ( self InLastStand() && !self InFinalStand() ) + { continue; + } if ( self HasThreat() ) + { continue; + } self bot_watch_think_mw2_loop(); } @@ -2811,20 +3312,28 @@ bot_watch_riot_weapons_loop() nade = self getValidGrenade(); if ( !isDefined( nade ) ) + { return; + } if ( dist <= level.bots_minGrenadeDistance || dist >= level.bots_maxGrenadeDistance ) + { return; + } if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["nade"] ) + { return; + } self botThrowGrenade( nade ); } else { if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["switch"] * 10 ) + { return; + } weaponslist = self getweaponslistall(); weap = ""; @@ -2835,20 +3344,28 @@ bot_watch_riot_weapons_loop() weaponslist = array_remove( weaponslist, weapon ); if ( !self getAmmoCount( weapon ) ) + { continue; + } if ( !isWeaponPrimary( weapon ) ) + { continue; + } if ( curWeap == weapon || weapon == "none" || weapon == "" || weapon == "javelin_mp" || weapon == "stinger_mp" || weapon == "onemanarmy_mp" ) + { continue; + } weap = weapon; break; } if ( weap == "" ) + { return; + } self thread ChangeToWeapon( weap ); } @@ -2868,22 +3385,34 @@ bot_watch_riot_weapons() wait randomIntRange( 2, 4 ); if ( self BotIsFrozen() ) + { continue; + } if ( self isDefusing() || self isPlanting() ) + { continue; + } if ( self IsUsingRemote() ) + { continue; + } if ( self InLastStand() && !self InFinalStand() ) + { continue; + } if ( !self HasThreat() ) + { continue; + } if ( !self.hasRiotShieldEquipped ) + { continue; + } self bot_watch_riot_weapons_loop(); } @@ -2895,7 +3424,9 @@ bot_watch_riot_weapons() bot_jav_loc_think_loop( data ) { if ( data.doFastContinue ) + { data.doFastContinue = false; + } else { wait randomintRange( 2, 4 ); @@ -2903,32 +3434,50 @@ bot_jav_loc_think_loop( data ) chance = self.pers["bots"]["behavior"]["nade"] / 2; if ( chance > 20 ) + { chance = 20; + } if ( randomInt( 100 ) > chance && self getCurrentWeapon() != "javelin_mp" ) + { return; + } } if ( !self GetAmmoCount( "javelin_mp" ) ) + { return; + } if ( self HasThreat() || self HasBotJavelinLocation() || self HasScriptAimPos() ) + { return; + } if ( self BotIsFrozen() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self InLastStand() && !self InFinalStand() ) + { return; + } if ( self isEMPed() ) + { return; + } loc = undefined; @@ -2941,18 +3490,26 @@ bot_jav_loc_think_loop( data ) traceForward = self maps\mp\_javelin::EyeTraceForward(); if ( !isDefined( traceForward ) ) + { return; + } loc = traceForward[0]; if ( self maps\mp\_javelin::TargetPointTooClose( loc ) ) + { return; + } if ( !bulletTracePassed( self.origin + ( 0, 0, 5 ), self.origin + ( 0, 0, 2048 ), false, self ) ) + { return; + } if ( !bulletTracePassed( loc + ( 0, 0, 5 ), loc + ( 0, 0, 2048 ), false, self ) ) + { return; + } } else { @@ -2963,10 +3520,14 @@ bot_jav_loc_think_loop( data ) ret = self waittill_any_return( "new_goal", "goal", "bad_path" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } if ( ret != "goal" ) + { return; + } data.doFastContinue = true; return; @@ -2979,7 +3540,9 @@ bot_jav_loc_think_loop( data ) } if ( !isDefined( loc ) ) + { return; + } self BotNotifyBotEvent( "jav", "start", loc ); @@ -3029,22 +3592,34 @@ bot_equipment_kill_think_loop() item = grenades[i]; if ( !isDefined( item ) ) + { continue; + } if ( !IsDefined( item.name ) ) + { continue; + } if ( IsDefined( item.owner ) && ( ( level.teamBased && item.owner.team == self.team ) || item.owner == self ) ) + { continue; + } if ( item.name != "c4_mp" && item.name != "claymore_mp" ) + { continue; + } if ( !hasSitrep && !bulletTracePassed( myEye, item.origin, false, item ) ) + { continue; + } if ( getConeDot( item.origin, self.origin, myAngles ) < 0.6 ) + { continue; + } if ( DistanceSquared( item.origin, self.origin ) < dist ) { @@ -3062,30 +3637,46 @@ bot_equipment_kill_think_loop() player = level.players[i]; if ( player == self ) + { continue; + } if ( !isDefined( player.team ) ) + { continue; + } if ( level.teamBased && player.team == myteam ) + { continue; + } ti = player.setSpawnPoint; if ( !isDefined( ti ) ) + { continue; + } if ( !isDefined( ti.bots ) ) + { ti.bots = 0; + } if ( ti.bots >= 2 ) + { continue; + } if ( !hasSitrep && !bulletTracePassed( myEye, ti.origin, false, ti ) ) + { continue; + } if ( getConeDot( ti.origin, self.origin, myAngles ) < 0.6 ) + { continue; + } if ( DistanceSquared( ti.origin, self.origin ) < dist ) { @@ -3096,7 +3687,9 @@ bot_equipment_kill_think_loop() } if ( !IsDefined( target ) ) + { return; + } if ( isDefined( target.enemyTrigger ) && !self HasScriptGoal() && !self.bot_lock_goal ) { @@ -3109,10 +3702,14 @@ bot_equipment_kill_think_loop() path = self waittill_any_return( "bad_path", "goal", "new_goal" ); if ( path != "new_goal" ) + { self ClearScriptGoal(); + } if ( path != "goal" || !isDefined( target ) ) + { return; + } if ( randomInt( 100 ) < self.pers["bots"]["behavior"]["camp"] * 8 ) { @@ -3155,10 +3752,14 @@ bot_equipment_kill_think() wait( RandomIntRange( 1, 3 ) ); if ( self HasScriptEnemy() ) + { continue; + } if ( self.pers["bots"]["skill"]["base"] <= 1 ) + { continue; + } self bot_equipment_kill_think_loop(); } @@ -3190,7 +3791,9 @@ bot_listen_to_steps_loop() dist = level.bots_listenDist; if ( self _hasPerk( "specialty_selectivehearing" ) ) + { dist *= 1.4; + } dist *= dist; @@ -3201,25 +3804,39 @@ bot_listen_to_steps_loop() player = level.players[i]; if ( player == self ) + { continue; + } if ( level.teamBased && self.team == player.team ) + { continue; + } if ( player.sessionstate != "playing" ) + { continue; + } if ( !isReallyAlive( player ) ) + { continue; + } if ( lengthsquared( player getVelocity() ) < 20000 ) + { continue; + } if ( distanceSquared( player.origin, self.origin ) > dist ) + { continue; + } if ( player _hasPerk( "specialty_quieter" ) ) + { continue; + } heard = player; break; @@ -3235,25 +3852,39 @@ bot_listen_to_steps_loop() player = level.players[i]; if ( player == self ) + { continue; + } if ( level.teamBased && self.team == player.team ) + { continue; + } if ( player.sessionstate != "playing" ) + { continue; + } if ( !isReallyAlive( player ) ) + { continue; + } if ( player _hasPerk( "specialty_heartbreaker" ) ) + { continue; + } if ( distanceSquared( player.origin, self.origin ) > heartbeatDist ) + { continue; + } if ( GetConeDot( player.origin, self.origin, self GetPlayerAngles() ) < 0.6 ) + { continue; + } heard = player; break; @@ -3261,7 +3892,9 @@ bot_listen_to_steps_loop() } if ( !IsDefined( heard ) ) + { return; + } self BotNotifyBotEvent( "heard_target", "start", heard ); @@ -3272,12 +3905,16 @@ bot_listen_to_steps_loop() } if ( self HasScriptGoal() || self.bot_lock_goal ) + { return; + } self SetScriptGoal( heard.origin, 64 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self BotNotifyBotEvent( "heard_target", "stop", heard ); } @@ -3295,7 +3932,9 @@ bot_listen_to_steps() wait 1; if ( self.pers["bots"]["skill"]["base"] < 3 ) + { continue; + } self bot_listen_to_steps_loop(); } @@ -3309,7 +3948,9 @@ bot_uav_think_loop() hasRadar = ( ( level.teamBased && level.activeUAVs[self.team] ) || ( !level.teamBased && level.activeUAVs[self.guid] ) ); if ( level.hardcoreMode && !hasRadar ) + { return; + } dist = self.pers["bots"]["skill"]["help_dist"]; dist *= dist * 8; @@ -3319,24 +3960,36 @@ bot_uav_think_loop() player = level.players[i]; if ( player == self ) + { continue; + } if ( !isDefined( player.team ) ) + { continue; + } if ( player.sessionstate != "playing" ) + { continue; + } if ( level.teambased && player.team == self.team ) + { continue; + } if ( !isReallyAlive( player ) ) + { continue; + } distFromPlayer = DistanceSquared( self.origin, player.origin ); if ( distFromPlayer > dist ) + { continue; + } if ( ( !isSubStr( player getCurrentWeapon(), "_silencer_" ) && player.bots_firing ) || ( hasRadar && !player _hasPerk( "specialty_coldblooded" ) ) ) { @@ -3355,7 +4008,9 @@ bot_uav_think_loop() self thread stop_go_target_on_death( player ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self BotNotifyBotEvent( "uav_target", "stop", player ); } @@ -3378,16 +4033,24 @@ bot_uav_think() wait 0.75; if ( self.pers["bots"]["skill"]["base"] <= 1 || self IsUsingRemote() ) + { continue; + } if ( self isEMPed() || self.bot_isScrambled ) + { continue; + } if ( self _hasPerk( "_specialty_blastshield" ) ) + { continue; + } if ( ( level.teamBased && level.activeCounterUAVs[level.otherTeam[self.team]] ) || ( !level.teamBased && self.isRadarBlocked ) ) + { continue; + } self bot_uav_think_loop(); } @@ -3402,7 +4065,9 @@ bot_revenge_think() self endon( "disconnect" ); if ( self.pers["bots"]["skill"]["base"] <= 1 ) + { return; + } if ( isDefined( self.lastKiller ) && isReallyAlive( self.lastKiller ) ) { @@ -3413,7 +4078,9 @@ bot_revenge_think() } if ( !isDefined( self.killerLocation ) ) + { return; + } loc = self.killerLocation; @@ -3422,17 +4089,23 @@ bot_revenge_think() wait( RandomIntRange( 1, 5 ) ); if ( self HasScriptGoal() || self.bot_lock_goal ) + { return; + } if ( randomint( 100 ) < 75 ) + { return; + } self BotNotifyBotEvent( "revenge", "start", loc, self.lastKiller ); self SetScriptGoal( loc, 64 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self BotNotifyBotEvent( "revenge", "stop", loc, self.lastKiller ); } @@ -3454,13 +4127,19 @@ turret_death_monitor( turret ) wait 0.5; if ( !isDefined( turret ) ) + { break; + } if ( turret.health <= 20000 ) + { break; + } if ( isDefined( turret.carriedBy ) ) + { break; + } } self notify( "bad_path" ); @@ -3478,13 +4157,19 @@ bot_turret_attack( enemy ) wait( 1 ); if ( !IsDefined( enemy ) ) + { return; + } if ( enemy.health <= 20000 ) + { return; + } if ( isDefined( enemy.carriedBy ) ) + { return; + } //if ( !BulletTracePassed( self getEye(), enemy.origin + ( 0, 0, 15 ), false, enemy ) ) // return; @@ -3506,10 +4191,14 @@ bot_turret_think_loop() } if ( self.pers["bots"]["skill"]["base"] <= 1 ) + { return; + } if ( self HasScriptEnemy() || self IsUsingRemote() ) + { return; + } myEye = self GetEye(); turret = undefined; @@ -3519,22 +4208,34 @@ bot_turret_think_loop() tempTurret = level.turrets[turretsKeys[i]]; if ( !isDefined( tempTurret ) ) + { continue; + } if ( tempTurret.health <= 20000 ) + { continue; + } if ( isDefined( tempTurret.carriedBy ) ) + { continue; + } if ( isDefined( tempTurret.owner ) && tempTurret.owner == self ) + { continue; + } if ( level.teamBased && tempTurret.team == myteam ) + { continue; + } if ( !bulletTracePassed( myEye, tempTurret.origin + ( 0, 0, 15 ), false, tempTurret ) ) + { continue; + } turret = tempTurret; } @@ -3542,7 +4243,9 @@ bot_turret_think_loop() turretsKeys = undefined; if ( !isDefined( turret ) ) + { return; + } forward = AnglesToForward( turret.angles ); forward = VectorNormalize( forward ); @@ -3555,22 +4258,34 @@ bot_turret_think_loop() facing = true; if ( dot < 0.342 ) // cos 70 degrees + { facing = false; + } if ( turret isStunned() ) + { facing = false; + } if ( self _hasPerk( "specialty_coldblooded" ) ) + { facing = false; + } if ( facing && !BulletTracePassed( myEye, turret.origin + ( 0, 0, 15 ), false, turret ) ) + { return; + } if ( !IsDefined( turret.bots ) ) + { turret.bots = 0; + } if ( turret.bots >= 2 ) + { return; + } if ( !facing && !self HasScriptGoal() && !self.bot_lock_goal ) { @@ -3582,11 +4297,15 @@ bot_turret_think_loop() self thread bots_watch_touch_obj( turret ); if ( self waittill_any_return( "bad_path", "goal", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } if ( !isDefined( turret ) ) + { return; + } self BotNotifyBotEvent( "turret_attack", "start", turret ); @@ -3622,7 +4341,9 @@ bot_watch_stuck_on_crate_loop() crates = getEntArray( "care_package", "targetname" ); if ( crates.size == 0 ) + { return; + } crate = undefined; @@ -3631,24 +4352,34 @@ bot_watch_stuck_on_crate_loop() tempCrate = crates[i]; if ( !isDefined( tempCrate ) ) + { continue; + } if ( !isDefined( tempCrate.doingPhysics ) || tempCrate.doingPhysics ) + { continue; + } if ( isDefined( crate ) && DistanceSquared( crate.origin, self.origin ) < DistanceSquared( tempCrate.origin, self.origin ) ) + { continue; + } crate = tempCrate; } if ( !isDefined( crate ) ) + { return; + } radius = GetDvarFloat( "player_useRadius" ); if ( DistanceSquared( crate.origin, self.origin ) > radius * radius ) + { return; + } self.bot_stuck_on_carepackage = crate; self notify( "crate_physics_done" ); @@ -3668,7 +4399,9 @@ bot_watch_stuck_on_crate() wait 3; if ( self HasThreat() ) + { continue; + } self bot_watch_stuck_on_crate_loop(); } @@ -3682,9 +4415,13 @@ bot_crate_think_loop( data ) ret = "crate_physics_done"; if ( data.first ) + { data.first = false; + } else + { ret = self waittill_any_timeout( randomintrange( 3, 5 ), "crate_physics_done" ); + } myteam = self.pers[ "team" ]; crate = self.bot_stuck_on_carepackage; @@ -3693,24 +4430,36 @@ bot_crate_think_loop( data ) if ( !isDefined( crate ) ) { if ( RandomInt( 100 ) < 20 && ret != "crate_physics_done" ) + { return; + } if ( self HasScriptGoal() || self.bot_lock_goal ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() || self BotIsFrozen() ) + { return; + } if ( self inLastStand() ) + { return; + } crates = getEntArray( "care_package", "targetname" ); if ( crates.size == 0 ) + { return; + } wantsClosest = randomint( 2 ); @@ -3721,28 +4470,40 @@ bot_crate_think_loop( data ) tempCrate = crates[i]; if ( !isDefined( tempCrate ) ) + { continue; + } if ( !isDefined( tempCrate.doingPhysics ) || tempCrate.doingPhysics ) + { continue; + } if ( !IsDefined( tempCrate.bots ) ) + { tempCrate.bots = 0; + } if ( tempCrate.bots >= 3 ) + { continue; + } if ( isDefined( crate ) ) { if ( wantsClosest ) { if ( DistanceSquared( crate.origin, self.origin ) < DistanceSquared( tempCrate.origin, self.origin ) ) + { continue; + } } else { if ( maps\mp\killstreaks\_killstreaks::getStreakCost( crate.crateType ) > maps\mp\killstreaks\_killstreaks::getStreakCost( tempCrate.crateType ) ) + { continue; + } } } @@ -3752,7 +4513,9 @@ bot_crate_think_loop( data ) crates = undefined; if ( !isDefined( crate ) ) + { return; + } self BotNotifyBotEvent( "crate_cap", "go", crate ); @@ -3768,12 +4531,16 @@ bot_crate_think_loop( data ) self.bot_lock_goal = false; if ( path != "new_goal" ) + { self ClearScriptGoal(); + } if ( path != "goal" || !isDefined( crate ) || DistanceSquared( self.origin, crate.origin ) > radius * radius ) { if ( isDefined( crate ) && path == "bad_path" ) + { self BotNotifyBotEvent( "crate_cap", "unreachable", crate ); + } return; } @@ -3789,7 +4556,9 @@ bot_crate_think_loop( data ) waitTime = 3.25; if ( !isDefined( crate.owner ) || crate.owner == self ) + { waitTime = 0.75; + } self thread BotPressUse( waitTime ); wait waitTime; @@ -3826,32 +4595,46 @@ doReloadCancel_loop() ret = self waittill_any_return( "reload", "weapon_change" ); if ( self BotIsFrozen() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self InLastStand() && !self InFinalStand() ) + { return; + } curWeap = self GetCurrentWeapon(); if ( !maps\mp\gametypes\_weapons::isPrimaryWeapon( 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(); @@ -3863,17 +4646,23 @@ doReloadCancel_loop() weaponslist = array_remove( weaponslist, weapon ); if ( !maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) ) + { continue; + } if ( curWeap == weapon || weapon == "none" || weapon == "" ) + { continue; + } weap = weapon; break; } if ( weap == "" ) + { return; + } // do the cancel wait 0.1; @@ -3905,16 +4694,24 @@ bot_weapon_think_loop( data ) ret = self waittill_any_timeout( randomIntRange( 2, 4 ), "bot_force_check_switch" ); if ( self BotIsFrozen() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self InLastStand() && !self InFinalStand() ) + { return; + } curWeap = self GetCurrentWeapon(); hasTarget = self hasThreat(); @@ -3927,7 +4724,9 @@ bot_weapon_think_loop( data ) if ( entIsVehicle( threat ) && isDefined( rocketAmmo ) ) { if ( curWeap != rocketAmmo ) + { self thread ChangeToWeapon( rocketAmmo ); + } return; } @@ -3936,7 +4735,9 @@ bot_weapon_think_loop( data ) if ( self HasBotJavelinLocation() && self GetAmmoCount( "javelin_mp" ) ) { if ( curWeap != "javelin_mp" ) + { self thread ChangeToWeapon( "javelin_mp" ); + } return; } @@ -3944,7 +4745,9 @@ bot_weapon_think_loop( data ) if ( isDefined( self.bot_oma_class ) ) { if ( curWeap != "onemanarmy_mp" ) + { self thread ChangeToWeapon( "onemanarmy_mp" ); + } return; } @@ -3956,20 +4759,28 @@ bot_weapon_think_loop( data ) data.first = false; if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["initswitch"] ) + { return; + } } else { if ( curWeap != "none" && self getAmmoCount( curWeap ) && curWeap != "stinger_mp" && curWeap != "javelin_mp" && curWeap != "onemanarmy_mp" ) { if ( randomInt( 100 ) > self.pers["bots"]["behavior"]["switch"] ) + { return; + } if ( hasTarget ) + { return; + } } else + { force = true; + } } weaponslist = self getweaponslistall(); @@ -3981,20 +4792,28 @@ bot_weapon_think_loop( data ) weaponslist = array_remove( weaponslist, weapon ); if ( !self getAmmoCount( weapon ) && !force ) + { continue; + } if ( !isWeaponPrimary( weapon ) ) + { continue; + } if ( curWeap == weapon || weapon == "none" || weapon == "" || weapon == "javelin_mp" || weapon == "stinger_mp" || weapon == "onemanarmy_mp" ) + { continue; + } weap = weapon; break; } if ( weap == "" ) + { return; + } self thread ChangeToWeapon( weap ); } @@ -4025,15 +4844,21 @@ bot_target_vehicle_loop() rocketAmmo = self getRocketAmmo(); if ( !isDefined( rocketAmmo ) && self BotGetRandom() < 90 ) + { return; + } if ( isDefined( rocketAmmo ) && rocketAmmo == "javelin_mp" && self isEMPed() ) + { return; + } targets = maps\mp\_stinger::GetTargetList(); if ( !targets.size ) + { return; + } lockOnAmmo = self getLockonAmmo(); myEye = self GetEye(); @@ -4044,16 +4869,24 @@ bot_target_vehicle_loop() tempTarget = targets[i]; if ( isDefined( tempTarget.owner ) && tempTarget.owner == self ) + { continue; + } if ( !bulletTracePassed( myEye, tempTarget.origin, false, tempTarget ) ) + { continue; + } if ( tempTarget.health <= 0 ) + { continue; + } if ( tempTarget.classname != "script_vehicle" && !isDefined( lockOnAmmo ) ) + { continue; + } target = tempTarget; } @@ -4061,7 +4894,9 @@ bot_target_vehicle_loop() targets = undefined; if ( !isDefined( target ) ) + { return; + } self BotNotifyBotEvent( "attack_vehicle", "start", target, rocketAmmo ); @@ -4086,13 +4921,19 @@ bot_target_vehicle() wait randomIntRange( 2, 4 ); if ( self.pers["bots"]["skill"]["base"] <= 1 ) + { continue; + } if ( self HasScriptEnemy() ) + { continue; + } if ( self IsUsingRemote() ) + { continue; + } self bot_target_vehicle_loop(); } @@ -4132,25 +4973,39 @@ getKillstreakTargetLocation() player = level.players[i]; if ( player == self ) + { continue; + } if ( !isDefined( player.team ) ) + { continue; + } if ( level.teamBased && self.team == player.team ) + { continue; + } if ( player.sessionstate != "playing" ) + { continue; + } if ( !isReallyAlive( player ) ) + { continue; + } if ( player _hasPerk( "specialty_coldblooded" ) ) + { continue; + } if ( !bulletTracePassed( player.origin, player.origin + ( 0, 0, 2048 ), false, player ) && self.pers["bots"]["skill"]["base"] > 3 ) + { continue; + } players[players.size] = player; } @@ -4158,9 +5013,13 @@ getKillstreakTargetLocation() target = random( players ); if ( isDefined( target ) ) + { location = target.origin + ( randomIntRange( ( 8 - self.pers["bots"]["skill"]["base"] ) * -75, ( 8 - self.pers["bots"]["skill"]["base"] ) * 75 ), randomIntRange( ( 8 - self.pers["bots"]["skill"]["base"] ) * -75, ( 8 - self.pers["bots"]["skill"]["base"] ) * 75 ), 0 ); + } else if ( self.pers["bots"]["skill"]["base"] <= 3 ) + { location = self.origin + ( randomIntRange( -512, 512 ), randomIntRange( -512, 512 ), 0 ); + } return location; } @@ -4176,10 +5035,14 @@ clear_remote_on_death( isac130 ) self waittill_either( "death", "disconnect" ); if ( isDefined( isac130 ) && isac130 ) + { level.ac130InUse = false; + } if ( isDefined( self ) ) + { self ClearUsingRemote(); + } } /* @@ -4188,20 +5051,28 @@ clear_remote_on_death( isac130 ) isAnyEnemyPlanes() { if ( !isDefined( level.harriers ) ) + { return false; + } for ( i = 0; i < level.harriers.size; i++ ) { plane = level.harriers[i]; if ( !isDefined( plane ) ) + { continue; + } if ( level.teamBased && plane.team == self.team ) + { continue; + } if ( isDefined( plane.owner ) && plane.owner == self ) + { continue; + } return true; } @@ -4215,65 +5086,95 @@ isAnyEnemyPlanes() bot_killstreak_think_loop( data ) { if ( data.doFastContinue ) + { data.doFastContinue = false; + } else { wait randomIntRange( 1, 3 ); } if ( !isDefined( self.pers["killstreaks"][0] ) ) + { return; + } if ( self BotIsFrozen() ) + { return; + } if ( self HasThreat() || self HasBotJavelinLocation() ) + { return; + } if ( self isDefusing() || self isPlanting() ) + { return; + } if ( self isEMPed() ) + { return; + } if ( self IsUsingRemote() ) + { return; + } if ( self InLastStand() && !self InFinalStand() ) + { return; + } if ( isDefined( self.isCarrying ) && self.isCarrying ) + { self notify( "place_sentry" ); + } curWeap = self GetCurrentWeapon(); if ( isSubStr( curWeap, "airdrop_" ) ) + { self thread BotPressAttack( 0.05 ); + } streakName = self.pers["killstreaks"][0].streakName; if ( level.inGracePeriod && maps\mp\killstreaks\_killstreaks::deadlyKillstreak( streakName ) ) + { return; + } ksWeap = maps\mp\killstreaks\_killstreaks::getKillstreakWeapon( streakName ); if ( curWeap == "none" || !isWeaponPrimary( curWeap ) ) + { curWeap = self GetLastWeapon(); + } lifeId = self.pers["killstreaks"][0].lifeId; if ( !isDefined( lifeId ) ) + { lifeId = -1; + } if ( isStrStart( streakName, "helicopter_" ) && self isAnyEnemyPlanes() && self.pers["bots"]["skill"]["base"] > 3 ) + { return; + } if ( maps\mp\killstreaks\_killstreaks::isRideKillstreak( streakName ) || maps\mp\killstreaks\_killstreaks::isCarryKillstreak( streakName ) ) { if ( self inLastStand() ) + { return; + } if ( lifeId == self.deaths && !self HasScriptGoal() && !self.bot_lock_goal && streakName != "sentry" && !self nearAnyOfWaypoints( 128, getWaypointsOfType( "camp" ) ) ) { @@ -4286,7 +5187,9 @@ bot_killstreak_think_loop( data ) self SetScriptGoal( campSpot.origin, 16 ); if ( self waittill_any_return( "new_goal", "goal", "bad_path" ) != "new_goal" ) + { self ClearScriptGoal(); + } data.doFastContinue = true; return; @@ -4296,7 +5199,9 @@ bot_killstreak_think_loop( data ) if ( streakName == "sentry" ) { if ( self HasScriptAimPos() ) + { return; + } myEye = self GetEye(); angles = self GetPlayerAngles(); @@ -4304,7 +5209,9 @@ bot_killstreak_think_loop( data ) forwardTrace = bulletTrace( myEye, myEye + AnglesToForward( angles ) * 1024, false, self ); if ( DistanceSquared( self.origin, forwardTrace["position"] ) < 1000 * 1000 && self.pers["bots"]["skill"]["base"] > 3 ) + { return; + } self BotNotifyBotEvent( "killstreak", "call", streakName ); @@ -4332,7 +5239,9 @@ bot_killstreak_think_loop( data ) location = self getKillstreakTargetLocation(); if ( !isDefined( location ) ) + { return; + } self BotNotifyBotEvent( "killstreak", "call", streakName, location ); @@ -4385,7 +5294,9 @@ bot_killstreak_think_loop( data ) else if ( streakName == "ac130" ) { if ( isDefined( level.ac130player ) || level.ac130InUse ) + { return; + } self BotNotifyBotEvent( "killstreak", "call", streakName ); @@ -4399,7 +5310,9 @@ bot_killstreak_think_loop( data ) else if ( streakName == "helicopter_minigun" ) { if ( isDefined( level.chopper ) ) + { return; + } self BotNotifyBotEvent( "killstreak", "call", streakName ); @@ -4416,13 +5329,19 @@ bot_killstreak_think_loop( data ) if ( streakName == "airdrop_mega" || streakName == "airdrop_sentry_minigun" || streakName == "airdrop" ) { if ( self HasScriptAimPos() ) + { return; + } if ( streakName != "airdrop_mega" && level.littleBirds > 2 ) + { return; + } if ( !bulletTracePassed( self.origin, self.origin + ( 0, 0, 2048 ), false, self ) && self.pers["bots"]["skill"]["base"] > 3 ) + { return; + } myEye = self GetEye(); angles = self GetPlayerAngles(); @@ -4430,10 +5349,14 @@ bot_killstreak_think_loop( data ) forwardTrace = bulletTrace( myEye, myEye + AnglesToForward( angles ) * 256, false, self ); if ( DistanceSquared( self.origin, forwardTrace["position"] ) < 96 * 96 && self.pers["bots"]["skill"]["base"] > 3 ) + { return; + } if ( !bulletTracePassed( forwardTrace["position"], forwardTrace["position"] + ( 0, 0, 2048 ), false, self ) && self.pers["bots"]["skill"]["base"] > 3 ) + { return; + } self BotNotifyBotEvent( "killstreak", "call", streakName ); @@ -4461,7 +5384,9 @@ bot_killstreak_think_loop( data ) } if ( randomInt( 100 ) < 80 && !self HasScriptGoal() && !self.bot_lock_goal ) + { self waittill_any_timeout( 15, "crate_physics_done", "new_goal" ); + } self BotStopMoving( false ); self ClearScriptAimPos(); @@ -4469,19 +5394,29 @@ bot_killstreak_think_loop( data ) else { if ( streakName == "harrier_airstrike" && level.planes > 1 ) + { return; + } if ( streakName == "nuke" && isDefined( level.nukeIncoming ) ) + { return; + } if ( streakName == "counter_uav" && self.pers["bots"]["skill"]["base"] > 3 && ( ( level.teamBased && level.activeCounterUAVs[self.team] ) || ( !level.teamBased && level.activeCounterUAVs[self.guid] ) ) ) + { return; + } if ( streakName == "uav" && self.pers["bots"]["skill"]["base"] > 3 && ( ( level.teamBased && ( level.activeUAVs[self.team] || level.activeCounterUAVs[level.otherTeam[self.team]] ) ) || ( !level.teamBased && ( level.activeUAVs[self.guid] || self.isRadarBlocked ) ) ) ) + { return; + } if ( streakName == "emp" && self.pers["bots"]["skill"]["base"] > 3 && ( ( level.teamBased && level.teamEMPed[level.otherTeam[self.team]] ) || ( !level.teamBased && isDefined( level.empPlayer ) ) ) ) + { return; + } location = undefined; directionYaw = undefined; @@ -4495,7 +5430,9 @@ bot_killstreak_think_loop( data ) directionYaw = randomInt( 360 ); if ( !isDefined( location ) ) + { return; + } case "helicopter": case "helicopter_flares": @@ -4553,11 +5490,17 @@ bot_killstreak_think() BotRandomStance() { if ( randomInt( 100 ) < 80 ) + { self BotSetStance( "prone" ); + } else if ( randomInt( 100 ) < 60 ) + { self BotSetStance( "crouch" ); + } else + { self BotSetStance( "stand" ); + } } /* @@ -4572,16 +5515,24 @@ BotUseRandomEquipment() // in mw2, can only one of these... if ( self GetAmmoCount( "claymore_mp" ) ) + { nade = "claymore_mp"; + } if ( self GetAmmoCount( "flare_mp" ) ) + { nade = "flare_mp"; + } if ( self GetAmmoCount( "c4_mp" ) ) + { nade = "c4_mp"; + } if ( !isDefined( nade ) ) + { return; + } self botThrowGrenade( nade, 0.05 ); } @@ -4595,7 +5546,9 @@ BotLookAtRandomThing( obj_target ) self endon( "disconnect" ); if ( self HasScriptAimPos() ) + { return; + } rand = RandomInt( 100 ); @@ -4606,13 +5559,19 @@ BotLookAtRandomThing( obj_target ) player = level.players[i]; if ( !isDefined( player ) || !isDefined( player.team ) ) + { continue; + } if ( !isAlive( player ) ) + { continue; + } if ( level.teamBased && self.team == player.team ) + { continue; + } if ( !isDefined( nearestEnemy ) || DistanceSquared( self.origin, player.origin ) < DistanceSquared( self.origin, nearestEnemy.origin ) ) { @@ -4623,13 +5582,21 @@ BotLookAtRandomThing( obj_target ) origin = ( 0, 0, self GetPlayerViewHeight() ); if ( isDefined( nearestEnemy ) && DistanceSquared( self.origin, nearestEnemy.origin ) < 1024 * 1024 && rand < 40 ) + { origin += ( nearestEnemy.origin[0], nearestEnemy.origin[1], self.origin[2] ); + } else if ( isDefined( obj_target ) && rand < 50 ) + { origin += ( obj_target.origin[0], obj_target.origin[1], self.origin[2] ); + } else if ( rand < 85 ) + { origin += self.origin + AnglesToForward( ( 0, self.angles[1] - 180, 0 ) ) * 1024; + } else + { origin += self.origin + AnglesToForward( ( 0, RandomInt( 360 ), 0 ) ) * 1024; + } self SetScriptAimPos( origin ); wait 2; @@ -4651,17 +5618,25 @@ bot_do_random_action_for_objective( obj_target ) self.bot_random_obj_action = true; if ( randomInt( 100 ) < 80 ) + { self thread BotUseRandomEquipment(); + } if ( randomInt( 100 ) < 75 ) + { self thread BotLookAtRandomThing( obj_target ); + } } else { if ( self GetStance() != "prone" && randomInt( 100 ) < 15 ) + { self BotSetStance( "prone" ); + } else if ( randomInt( 100 ) < 5 ) + { self thread BotLookAtRandomThing( obj_target ); + } } wait 2; @@ -4678,28 +5653,38 @@ bot_dom_spawn_kill_think_loop() myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam ); if ( myFlagCount == level.flags.size ) + { return; + } otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); if ( myFlagCount <= otherFlagCount || otherFlagCount != 1 ) + { return; + } flag = undefined; for ( i = 0; i < level.flags.size; i++ ) { if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam ) + { continue; + } flag = level.flags[i]; } if ( !isDefined( flag ) ) + { return; + } if ( DistanceSquared( self.origin, flag.origin ) < 2048 * 2048 ) + { return; + } self BotNotifyBotEvent( "dom", "start", "spawnkill", flag ); @@ -4708,7 +5693,9 @@ bot_dom_spawn_kill_think_loop() self thread bot_dom_watch_flags( myFlagCount, myTeam ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self BotNotifyBotEvent( "dom", "stop", "spawnkill", flag ); } @@ -4722,17 +5709,23 @@ bot_dom_spawn_kill_think() self endon( "disconnect" ); if ( level.gametype != "dom" ) + { return; + } for ( ;; ) { wait( randomintrange( 10, 20 ) ); if ( randomint( 100 ) < 20 ) + { continue; + } if ( self HasScriptGoal() || self.bot_lock_goal ) + { continue; + } self bot_dom_spawn_kill_think_loop(); } @@ -4754,7 +5747,9 @@ bot_dom_watch_flags( count, myTeam ) wait 0.5; if ( maps\mp\gametypes\dom::getTeamFlagCount( myTeam ) != count ) + { break; + } } self notify( "bad_path" ); @@ -4771,17 +5766,25 @@ bot_dom_def_think_loop() for ( i = 0; i < level.flags.size; i++ ) { if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() != myTeam ) + { continue; + } if ( !level.flags[i].useObj.objPoints[myTeam].isFlashing ) + { continue; + } if ( !isDefined( flag ) || DistanceSquared( self.origin, level.flags[i].origin ) < DistanceSquared( self.origin, flag.origin ) ) + { flag = level.flags[i]; + } } if ( !isDefined( flag ) ) + { return; + } self BotNotifyBotEvent( "dom", "start", "defend", flag ); @@ -4791,7 +5794,9 @@ bot_dom_def_think_loop() self thread bots_watch_touch_obj( flag ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self BotNotifyBotEvent( "dom", "stop", "defend", flag ); } @@ -4805,17 +5810,23 @@ bot_dom_def_think() self endon( "disconnect" ); if ( level.gametype != "dom" ) + { return; + } for ( ;; ) { wait( randomintrange( 1, 3 ) ); if ( randomint( 100 ) < 35 ) + { continue; + } if ( self HasScriptGoal() || self.bot_lock_goal ) + { continue; + } self bot_dom_def_think_loop(); } @@ -4837,10 +5848,14 @@ bot_dom_watch_for_flashing( flag, myTeam ) wait 0.5; if ( !isDefined( flag ) ) + { break; + } if ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam || !flag.useObj.objPoints[myTeam].isFlashing ) + { break; + } } self notify( "bad_path" ); @@ -4857,7 +5872,9 @@ bot_dom_cap_think_loop() myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam ); if ( myFlagCount == level.flags.size ) + { return; + } otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); @@ -4866,17 +5883,23 @@ bot_dom_cap_think_loop() if ( myFlagCount < otherFlagCount ) { if ( randomint( 100 ) < 15 ) + { return; + } } else if ( myFlagCount == otherFlagCount ) { if ( randomint( 100 ) < 35 ) + { return; + } } else if ( myFlagCount > otherFlagCount ) { if ( randomint( 100 ) < 95 ) + { return; + } } } @@ -4886,7 +5909,9 @@ bot_dom_cap_think_loop() for ( i = 0; i < level.flags.size; i++ ) { if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam ) + { continue; + } flags[flags.size] = level.flags[i]; } @@ -4896,7 +5921,9 @@ bot_dom_cap_think_loop() for ( i = 0; i < flags.size; i++ ) { if ( !isDefined( flag ) || DistanceSquared( self.origin, level.flags[i].origin ) < DistanceSquared( self.origin, flag.origin ) ) + { flag = level.flags[i]; + } } } else if ( flags.size ) @@ -4905,7 +5932,9 @@ bot_dom_cap_think_loop() } if ( !isDefined( flag ) ) + { return; + } self BotNotifyBotEvent( "dom", "go", "cap", flag ); @@ -4917,7 +5946,9 @@ bot_dom_cap_think_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" ) { @@ -4935,7 +5966,9 @@ bot_dom_cap_think_loop() wait 0.5; if ( flag.useObj.curProgress == cur ) + { break;//some enemy is near us, kill him + } self thread bot_do_random_action_for_objective( flag ); } @@ -4956,7 +5989,9 @@ bot_dom_cap_think() self endon( "disconnect" ); if ( level.gametype != "dom" ) + { return; + } for ( ;; ) { @@ -4968,7 +6003,9 @@ bot_dom_cap_think() } if ( !isDefined( level.flags ) || level.flags.size == 0 ) + { continue; + } self bot_dom_cap_think_loop(); } @@ -4990,19 +6027,29 @@ bot_dom_go_cap_flag( flag, myteam ) wait randomintrange( 2, 4 ); if ( !isDefined( flag ) ) + { break; + } if ( flag maps\mp\gametypes\dom::getFlagTeam() == myTeam ) + { break; + } if ( self isTouching( flag ) ) + { break; + } } if ( flag maps\mp\gametypes\dom::getFlagTeam() == myTeam ) + { self notify( "bad_path" ); + } else + { self notify( "goal" ); + } } /* @@ -5023,15 +6070,21 @@ bot_hq_loop() if ( gameobj.interactTeam == "none" ) //wait for it to become active { if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5047,7 +6100,9 @@ bot_hq_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" ) { @@ -5071,7 +6126,9 @@ bot_hq_loop() wait 0.5; if ( cur == gameobj.curProgress ) + { break;//no prog made, enemy must be capping + } self thread bot_do_random_action_for_objective( gameobj.trigger ); } @@ -5092,7 +6149,9 @@ bot_hq_loop() self thread bot_hq_watch_flashing( gameobj, radio ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5101,15 +6160,21 @@ bot_hq_loop() } if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } } @@ -5122,7 +6187,9 @@ bot_hq() self endon( "disconnect" ); if ( level.gametype != "koth" ) + { return; + } for ( ;; ) { @@ -5134,10 +6201,14 @@ bot_hq() } if ( !isDefined( level.radio ) ) + { continue; + } if ( !isDefined( level.radio.gameobject ) ) + { continue; + } self bot_hq_loop(); } @@ -5159,19 +6230,29 @@ bot_hq_go_cap( obj, radio ) wait randomintrange( 2, 4 ); if ( !isDefined( obj ) ) + { break; + } if ( self isTouching( obj.trigger ) ) + { break; + } if ( level.radio != radio ) + { break; + } } if ( level.radio != radio ) + { self notify( "bad_path" ); + } else + { self notify( "goal" ); + } } /* @@ -5192,13 +6273,19 @@ bot_hq_watch_flashing( obj, radio ) wait 0.5; if ( !isDefined( obj ) ) + { break; + } if ( !obj.objPoints[myteam].isFlashing ) + { break; + } if ( level.radio != radio ) + { break; + } } self notify( "bad_path" ); @@ -5237,7 +6324,9 @@ bot_sab_loop() self thread bot_defend_site( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5247,13 +6336,17 @@ bot_sab_loop() //else hang around the site if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -5264,18 +6357,24 @@ bot_sab_loop() { // lets escort the bomb carrier if ( self HasScriptGoal() ) + { return; + } origin = carrier.origin; if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_escort_obj( bomb, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5284,7 +6383,9 @@ bot_sab_loop() timepassed = getTimePassed() / 1000; if ( timepassed < 120 && timeleft >= 90 && randomInt( 100 ) < 98 ) + { return; + } self BotNotifyBotEvent( "sab", "go", "plant" ); @@ -5295,7 +6396,9 @@ bot_sab_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || level.bombPlanted || !self isTouching( site.trigger ) || site IsInUse() || self inLastStand() || self HasThreat() ) { @@ -5323,7 +6426,9 @@ bot_sab_loop() site = level.bombZones[myteam]; if ( !isDefined( site.bots ) ) + { site.bots = 0; + } // protect our site from planters if ( !level.bombPlanted ) @@ -5332,10 +6437,14 @@ bot_sab_loop() if ( site.bots > 2 || randomInt( 100 ) < 45 ) { if ( self HasScriptGoal() ) + { return; + } if ( carrier _hasPerk( "specialty_coldblooded" ) ) + { return; + } origin = carrier.origin; @@ -5343,7 +6452,9 @@ bot_sab_loop() self thread bot_escort_obj( bomb, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5364,7 +6475,9 @@ bot_sab_loop() self thread bot_defend_site( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5386,7 +6499,9 @@ bot_sab_loop() self thread bot_inc_bots( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -5399,16 +6514,22 @@ bot_sab_loop() if ( site.bots > 1 ) { if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_go_defuse( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5425,7 +6546,9 @@ bot_sab_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || !level.bombPlanted || site IsInUse() || !self isTouching( site.trigger ) || self InLastStand() || self HasThreat() ) { @@ -5460,7 +6583,9 @@ bot_sab_loop() self thread bot_get_obj( bomb ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5479,7 +6604,9 @@ bot_sab() level endon( "game_ended" ); if ( level.gametype != "sab" ) + { return; + } for ( ;; ) { @@ -5491,13 +6618,19 @@ bot_sab() } if ( !isDefined( level.sabBomb ) ) + { continue; + } if ( !isDefined( level.bombZones ) || !level.bombZones.size ) + { continue; + } if ( self IsPlanting() || self isDefusing() ) + { continue; + } self bot_sab_loop(); } @@ -5517,7 +6650,9 @@ bot_sd_defenders_loop( data ) timeleft = maps\mp\gametypes\_gamelogic::getTimeRemaining() / 1000; if ( timeleft >= 90 ) + { return; + } // check for a bomb carrier, and camp the bomb if ( !level.multiBomb && isDefined( level.sdBomb ) ) @@ -5531,17 +6666,23 @@ bot_sd_defenders_loop( data ) //hang around the bomb if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_get_obj( bomb ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5549,7 +6690,9 @@ bot_sd_defenders_loop( data ) // pick a site to protect if ( !isDefined( level.bombZones ) || !level.bombZones.size ) + { return; + } sites = []; @@ -5559,15 +6702,23 @@ bot_sd_defenders_loop( data ) } if ( !sites.size ) + { return; + } if ( data.rand > 50 ) + { site = self bot_array_nearest_curorigin( sites ); + } else + { site = random( sites ); + } if ( !isDefined( site ) ) + { return; + } origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 5 ); @@ -5581,7 +6732,9 @@ bot_sd_defenders_loop( data ) self thread bot_defend_site( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5591,13 +6744,17 @@ bot_sd_defenders_loop( data ) //else hang around the site if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -5605,12 +6762,16 @@ bot_sd_defenders_loop( data ) // bomb is planted, we need to defuse if ( !isDefined( level.defuseObject ) ) + { return; + } defuse = level.defuseObject; if ( !isDefined( defuse.bots ) ) + { defuse.bots = 0; + } origin = ( defuse.curorigin[0], defuse.curorigin[1], defuse.curorigin[2] + 5 ); @@ -5618,16 +6779,22 @@ bot_sd_defenders_loop( data ) if ( defuse.bots > 1 ) { if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_go_defuse( defuse ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5643,7 +6810,9 @@ bot_sd_defenders_loop( data ) event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || !level.bombPlanted || defuse isInUse() || !self isTouching( defuse.trigger ) || self InLastStand() || self HasThreat() ) { @@ -5677,10 +6846,14 @@ bot_sd_defenders() level endon( "game_ended" ); if ( level.gametype != "sd" ) + { return; + } if ( self.team == game["attackers"] ) + { return; + } data = spawnStruct(); data.rand = self BotGetRandom(); @@ -5695,7 +6868,9 @@ bot_sd_defenders() } if ( self IsPlanting() || self isDefusing() ) + { continue; + } self bot_sd_defenders_loop( data ); } @@ -5707,9 +6882,13 @@ bot_sd_defenders() bot_sd_attackers_loop( data ) { if ( data.first ) + { data.first = false; + } else + { wait( randomintrange( 3, 5 ) ); + } if ( self IsUsingRemote() || self.bot_lock_goal ) { @@ -5723,7 +6902,9 @@ bot_sd_attackers_loop( data ) if ( level.bombPlanted ) { if ( !isDefined( level.defuseObject ) ) + { return; + } site = level.defuseObject; @@ -5740,7 +6921,9 @@ bot_sd_attackers_loop( data ) self thread bot_defend_site( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5750,13 +6933,17 @@ bot_sd_attackers_loop( data ) //else hang around the site if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -5769,7 +6956,9 @@ bot_sd_attackers_loop( data ) if ( !self IsBombCarrier() && !level.multiBomb ) { if ( !isDefined( level.sdBomb ) ) + { return; + } bomb = level.sdBomb; carrier = level.sdBomb.carrier; @@ -5779,24 +6968,32 @@ bot_sd_attackers_loop( data ) { //escort the bomb carrier if ( self HasScriptGoal() ) + { return; + } origin = carrier.origin; if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_escort_obj( bomb, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } if ( !isDefined( bomb.bots ) ) + { bomb.bots = 0; + } origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 5 ); @@ -5804,17 +7001,23 @@ bot_sd_attackers_loop( data ) if ( bomb.bots > 1 ) { if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_get_obj( bomb ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -5828,7 +7031,9 @@ bot_sd_attackers_loop( data ) self thread bot_get_obj( bomb ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -5838,10 +7043,14 @@ bot_sd_attackers_loop( data ) // check if to plant if ( timepassed < 120 && timeleft >= 90 && randomInt( 100 ) < 98 ) + { return; + } if ( !isDefined( level.bombZones ) || !level.bombZones.size ) + { return; + } sites = []; @@ -5851,15 +7060,23 @@ bot_sd_attackers_loop( data ) } if ( !sites.size ) + { return; + } if ( data.rand > 50 ) + { plant = self bot_array_nearest_curorigin( sites ); + } else + { plant = random( sites ); + } if ( !isDefined( plant ) ) + { return; + } origin = ( plant.curorigin[0] + 50, plant.curorigin[1] + 50, plant.curorigin[2] + 5 ); @@ -5872,7 +7089,9 @@ bot_sd_attackers_loop( data ) event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || level.bombPlanted || plant.visibleTeam == "none" || !self isTouching( plant.trigger ) || self InLastStand() || self HasThreat() || plant IsInUse() ) { @@ -5906,10 +7125,14 @@ bot_sd_attackers() level endon( "game_ended" ); if ( level.gametype != "sd" ) + { return; + } if ( self.team != game["attackers"] ) + { return; + } data = spawnStruct(); data.rand = self BotGetRandom(); @@ -5974,10 +7197,14 @@ bot_cap_loop() else { if ( self HasScriptGoal() ) + { return; + } if ( !isDefined( theirzone.bots ) ) + { theirzone.bots = 0; + } origin = theirzone.curorigin; @@ -5985,7 +7212,9 @@ bot_cap_loop() { //kill carrier if ( carrier _hasPerk( "specialty_coldblooded" ) ) + { return; + } origin = carrier.origin; @@ -5993,7 +7222,9 @@ bot_cap_loop() self thread bot_escort_obj( myflag, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -6014,7 +7245,9 @@ bot_cap_loop() self thread bot_escort_obj( myflag, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } } } @@ -6036,7 +7269,9 @@ bot_cap_loop() wait 1; if ( evt != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -6059,18 +7294,24 @@ bot_cap_loop() //escort them if ( self HasScriptGoal() ) + { return; + } origin = carrier.origin; if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_escort_obj( theirflag, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } } @@ -6084,7 +7325,9 @@ bot_cap() level endon( "game_ended" ); if ( level.gametype != "ctf" ) + { return; + } for ( ;; ) { @@ -6096,10 +7339,14 @@ bot_cap() } if ( !isDefined( level.capZones ) ) + { continue; + } if ( !isDefined( level.teamFlags ) ) + { continue; + } self bot_cap_loop(); } @@ -6113,7 +7360,9 @@ getCarrierEntNum() carrierNum = -1; if ( isDefined( self.carrier ) ) + { carrierNum = self.carrier getEntityNumber(); + } return carrierNum; } @@ -6135,7 +7384,9 @@ bot_cap_get_flag( flag ) evt = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( evt != "new_goal" ) + { self ClearScriptGoal(); + } if ( evt != "goal" ) { @@ -6152,7 +7403,9 @@ bot_cap_get_flag( flag ) wait 0.5; if ( flag.curProgress == cur ) + { break;//some enemy is near us, kill him + } } self ClearScriptGoal(); @@ -6177,16 +7430,24 @@ bot_dem_go_plant( plant ) wait 0.5; if ( ( plant.label == "_b" && level.bombBPlanted ) || ( plant.label == "_a" && level.bombAPlanted ) ) + { break; + } if ( self isTouching( plant.trigger ) ) + { break; + } } if ( ( plant.label == "_b" && level.bombBPlanted ) || ( plant.label == "_a" && level.bombAPlanted ) ) + { self notify( "bad_path" ); + } else + { self notify( "goal" ); + } } /* @@ -6209,7 +7470,9 @@ bot_dem_attack_spawnkill() wait 0.5; if ( l1 != level.bombAPlanted || l2 != level.bombBPlanted ) + { break; + } } self notify( "bad_path" ); @@ -6240,9 +7503,13 @@ bot_dem_attackers_loop() if ( bomb.label == "_a" ) { if ( level.bombAPlanted ) + { bombs[bombs.size] = bomb; + } else + { sites[sites.size] = bomb; + } continue; } @@ -6250,9 +7517,13 @@ bot_dem_attackers_loop() if ( bomb.label == "_b" ) { if ( level.bombBPlanted ) + { bombs[bombs.size] = bomb; + } else + { sites[sites.size] = bomb; + } continue; } @@ -6268,24 +7539,32 @@ bot_dem_attackers_loop() if ( ( ( bombed + bombs.size == 1 && timeleft >= 90 ) || ( shouldLet && !bombs.size ) ) && randomInt( 100 ) < 95 ) { if ( self HasScriptGoal() ) + { return; + } spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_start" ); if ( !spawnPoints.size ) + { return; + } spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 2048 * 2048 ) + { return; + } self SetScriptGoal( spawnpoint.origin, 1024 ); self thread bot_dem_attack_spawnkill(); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -6298,18 +7577,24 @@ bot_dem_attackers_loop() spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_start" ); if ( !spawnPoints.size ) + { return; + } spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( spawnpoint.origin, 512 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -6332,7 +7617,9 @@ bot_dem_attackers_loop() self thread bot_defend_site( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -6342,13 +7629,17 @@ bot_dem_attackers_loop() //else hang around the site if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -6356,15 +7647,21 @@ bot_dem_attackers_loop() //else go plant if ( !sites.size ) + { return; + } plant = self bot_array_nearest_curorigin( sites ); if ( !isDefined( plant ) ) + { return; + } if ( !isDefined( plant.bots ) ) + { plant.bots = 0; + } origin = ( plant.curorigin[0] + 50, plant.curorigin[1] + 50, plant.curorigin[2] + 5 ); @@ -6372,16 +7669,22 @@ bot_dem_attackers_loop() if ( plant.bots > 1 && timeleft >= 60 ) { if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_dem_go_plant( plant ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -6397,7 +7700,9 @@ bot_dem_attackers_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || ( plant.label == "_b" && level.bombBPlanted ) || ( plant.label == "_a" && level.bombAPlanted ) || plant IsInUse() || !self isTouching( plant.trigger ) || self InLastStand() || self HasThreat() ) { @@ -6432,10 +7737,14 @@ bot_dem_attackers() level endon( "game_ended" ); if ( level.gametype != "dd" ) + { return; + } if ( self.team != game["attackers"] ) + { return; + } for ( ;; ) { @@ -6447,7 +7756,9 @@ bot_dem_attackers() } if ( !isDefined( level.bombZones ) || !level.bombZones.size ) + { continue; + } self bot_dem_attackers_loop(); } @@ -6478,9 +7789,13 @@ bot_dem_defenders_loop() if ( bomb.label == "_a" ) { if ( level.bombAPlanted ) + { bombs[bombs.size] = bomb; + } else + { sites[sites.size] = bomb; + } continue; } @@ -6488,9 +7803,13 @@ bot_dem_defenders_loop() if ( bomb.label == "_b" ) { if ( level.bombBPlanted ) + { bombs[bombs.size] = bomb; + } else + { sites[sites.size] = bomb; + } continue; } @@ -6506,24 +7825,32 @@ bot_dem_defenders_loop() if ( ( !bombs.size && timeleft >= 60 && randomInt( 100 ) < 95 ) || ( shouldLet && bombs.size == 1 ) ) { if ( self HasScriptGoal() ) + { return; + } spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_attacker_start" ); if ( !spawnPoints.size ) + { return; + } spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 2048 * 2048 ) + { return; + } self SetScriptGoal( spawnpoint.origin, 1024 ); self thread bot_dem_defend_spawnkill(); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -6536,18 +7863,24 @@ bot_dem_defenders_loop() spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dd_spawn_defender_start" ); if ( !spawnPoints.size ) + { return; + } spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( spawnpoint.origin, 512 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -6570,7 +7903,9 @@ bot_dem_defenders_loop() self thread bot_defend_site( site ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -6581,13 +7916,17 @@ bot_dem_defenders_loop() //else hang around the site if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -6596,15 +7935,21 @@ bot_dem_defenders_loop() //else go defuse if ( !bombs.size ) + { return; + } defuse = self bot_array_nearest_curorigin( bombs ); if ( !isDefined( defuse ) ) + { return; + } if ( !isDefined( defuse.bots ) ) + { defuse.bots = 0; + } origin = ( defuse.curorigin[0] + 50, defuse.curorigin[1] + 50, defuse.curorigin[2] + 5 ); @@ -6612,17 +7957,23 @@ bot_dem_defenders_loop() if ( defuse.bots > 1 && bombed + bombs.size != 2 ) { if ( self HasScriptGoal() ) + { return; + } if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_dem_go_defuse( defuse ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -6638,7 +7989,9 @@ bot_dem_defenders_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || ( defuse.label == "_b" && !level.bombBPlanted ) || ( defuse.label == "_a" && !level.bombAPlanted ) || defuse IsInUse() || !self isTouching( defuse.trigger ) || self InLastStand() || self HasThreat() ) { @@ -6673,10 +8026,14 @@ bot_dem_defenders() level endon( "game_ended" ); if ( level.gametype != "dd" ) + { return; + } if ( self.team == game["attackers"] ) + { return; + } for ( ;; ) { @@ -6688,7 +8045,9 @@ bot_dem_defenders() } if ( !isDefined( level.bombZones ) || !level.bombZones.size ) + { continue; + } self bot_dem_defenders_loop(); } @@ -6711,16 +8070,24 @@ bot_dem_go_defuse( defuse ) wait 0.5; if ( self isTouching( defuse.trigger ) ) + { break; + } if ( ( defuse.label == "_b" && !level.bombBPlanted ) || ( defuse.label == "_a" && !level.bombAPlanted ) ) + { break; + } } if ( ( defuse.label == "_b" && !level.bombBPlanted ) || ( defuse.label == "_a" && !level.bombAPlanted ) ) + { self notify( "bad_path" ); + } else + { self notify( "goal" ); + } } /* @@ -6740,7 +8107,9 @@ bot_dem_defend_spawnkill() wait 0.5; if ( level.bombBPlanted || level.bombAPlanted ) + { break; + } } self notify( "bad_path" ); @@ -6758,17 +8127,25 @@ bot_think_revive_loop() player = level.players[i]; if ( player.team != self.team ) + { continue; + } if ( distanceSquared( self.origin, player.origin ) >= 2048 * 2048 ) + { continue; + } if ( player inLastStand() ) + { needsRevives[needsRevives.size] = player; + } } if ( !needsRevives.size ) + { return; + } revive = random( needsRevives ); @@ -6781,12 +8158,16 @@ bot_think_revive_loop() ret = self waittill_any_return( "new_goal", "goal", "bad_path" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; if ( ret != "goal" || !isDefined( revive ) || distanceSquared( self.origin, revive.origin ) >= 100 * 100 || !revive inLastStand() || revive isBeingRevived() || !isAlive( revive ) ) + { return; + } self BotNotifyBotEvent( "revive", "start", revive ); @@ -6812,23 +8193,33 @@ bot_think_revive() level endon( "game_ended" ); if ( !level.dieHardMode || !level.teamBased ) + { return; + } for ( ;; ) { wait( randomintrange( 1, 3 ) ); if ( self HasScriptGoal() || self.bot_lock_goal ) + { continue; + } if ( self isDefusing() || self isPlanting() ) + { continue; + } if ( self IsUsingRemote() || self BotIsFrozen() ) + { continue; + } if ( self inLastStand() ) + { continue; + } self bot_think_revive_loop(); } @@ -6860,7 +8251,9 @@ bot_gtnw_loop() ret = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( ret != "new_goal" ) + { self ClearScriptGoal(); + } if ( ret != "goal" || !self isTouching( trigger ) ) { @@ -6878,7 +8271,9 @@ bot_gtnw_loop() wait 0.5; if ( cur == level.nukeSite.curProgress ) + { break;//no prog made, enemy must be capping + } self thread bot_do_random_action_for_objective( trigger ); } @@ -6899,7 +8294,9 @@ bot_gtnw_loop() self thread bots_watch_touch_obj( trigger ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; return; @@ -6907,13 +8304,17 @@ bot_gtnw_loop() //else hang around the site if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self.bot_lock_goal = true; self SetScriptGoal( origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; } @@ -6928,7 +8329,9 @@ bot_gtnw() level endon( "game_ended" ); if ( level.gametype != "gtnw" ) + { return; + } for ( ;; ) { @@ -6940,7 +8343,9 @@ bot_gtnw() } if ( !isDefined( level.nukeSite ) || !isDefined( level.nukeSite.trigger ) ) + { continue; + } self bot_gtnw_loop(); } @@ -6974,7 +8379,9 @@ bot_oneflag_loop() wait 1; if ( evt != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -6995,18 +8402,24 @@ bot_oneflag_loop() //escort them if ( self HasScriptGoal() ) + { return; + } origin = carrier.origin; if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_escort_obj( theirflag, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } else { @@ -7026,10 +8439,14 @@ bot_oneflag_loop() } if ( self HasScriptGoal() ) + { return; + } if ( !isDefined( theirzone.bots ) ) + { theirzone.bots = 0; + } origin = theirzone.curorigin; @@ -7037,7 +8454,9 @@ bot_oneflag_loop() { //kill carrier if ( carrier _hasPerk( "specialty_coldblooded" ) ) + { return; + } origin = carrier.origin; @@ -7045,7 +8464,9 @@ bot_oneflag_loop() self thread bot_escort_obj( myflag, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } return; } @@ -7066,24 +8487,32 @@ bot_oneflag_loop() self thread bot_escort_obj( myflag, carrier ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } else { // is home, lets hang around and protect if ( self HasScriptGoal() ) + { return; + } origin = myflag.curorigin; if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( origin, 256 ); self thread bot_get_obj( myflag ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } } } @@ -7098,7 +8527,9 @@ bot_oneflag() level endon( "game_ended" ); if ( level.gametype != "oneflag" ) + { return; + } for ( ;; ) { @@ -7110,7 +8541,9 @@ bot_oneflag() } if ( !isDefined( level.capZones ) || !isDefined( level.teamFlags ) ) + { continue; + } self bot_oneflag_loop(); } @@ -7132,7 +8565,9 @@ bot_arena_loop() event = self waittill_any_return( "goal", "bad_path", "new_goal" ); if ( event != "new_goal" ) + { self ClearScriptGoal(); + } if ( event != "goal" || !self isTouching( flag.trigger ) ) { @@ -7150,7 +8585,9 @@ bot_arena_loop() wait 0.5; if ( cur == flag.curProgress ) + { break;//no prog made, enemy must be capping + } self thread bot_do_random_action_for_objective( flag.trigger ); } @@ -7171,7 +8608,9 @@ bot_arena() level endon( "game_ended" ); if ( level.gametype != "arena" ) + { return; + } for ( ;; ) { @@ -7183,7 +8622,9 @@ bot_arena() } if ( !isDefined( level.arenaFlag ) ) + { continue; + } self bot_arena_loop(); } @@ -7207,10 +8648,14 @@ bot_vip_loop() player = level.players[i]; if ( !isReallyAlive( player ) ) + { continue; + } if ( isDefined( player.isVip ) && player.isVip ) + { vip = player; + } } if ( self.team == game["defenders"] ) @@ -7230,7 +8675,9 @@ bot_vip_loop() wait 1; if ( evt != "new_goal" ) + { self ClearScriptGoal(); + } self.bot_lock_goal = false; @@ -7241,12 +8688,16 @@ bot_vip_loop() { // protect the vip if ( DistanceSquared( vip.origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( vip.origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } } else @@ -7255,12 +8706,16 @@ bot_vip_loop() { // camp the extraction zone if ( DistanceSquared( level.extractionZone.trigger.origin, self.origin ) <= 1024 * 1024 ) + { return; + } self SetScriptGoal( level.extractionZone.trigger.origin, 256 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } else if ( isDefined( vip ) ) { @@ -7268,7 +8723,9 @@ bot_vip_loop() self SetScriptGoal( vip.origin, 32 ); if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) + { self ClearScriptGoal(); + } } } } @@ -7283,7 +8740,9 @@ bot_vip() level endon( "game_ended" ); if ( level.gametype != "vip" ) + { return; + } for ( ;; ) { diff --git a/maps/mp/bots/_bot_utility.gsc b/maps/mp/bots/_bot_utility.gsc index c4b2538..d7874e1 100644 --- a/maps/mp/bots/_bot_utility.gsc +++ b/maps/mp/bots/_bot_utility.gsc @@ -22,12 +22,18 @@ wait_for_builtins() for ( i = 0; i < 20; i++ ) { if ( isDefined( level.bot_builtins ) ) + { return true; + } if ( i < 18 ) + { waittillframeend; + } else + { wait 0.05; + } } return false; @@ -144,7 +150,9 @@ doHostCheck() self.pers["bot_host"] = false; if ( self is_bot() ) + { return; + } result = false; @@ -158,7 +166,9 @@ doHostCheck() } if ( getDvar( "bots_main_firstIsHost" ) == self getguid() + "" ) + { result = true; + } } DvarGUID = getDvar( "bots_main_GUIDs" ); @@ -170,12 +180,16 @@ doHostCheck() for ( i = 0; i < guids.size; i++ ) { if ( self getguid() + "" == guids[i] ) + { result = true; + } } } if ( !self isHost() && !result ) + { return; + } self.pers["bot_host"] = true; } @@ -258,7 +272,9 @@ BotPressAttack( time ) BotGetTargetRandom() { if ( !isDefined( self.bot.target ) ) + { return undefined; + } return self.bot.target.rand; } @@ -319,7 +335,9 @@ BotFreezeControls( what ) self.bot.isfrozen = what; if ( what ) + { self notify( "kill_goal" ); + } } /* @@ -338,7 +356,9 @@ BotStopMoving( what ) self.bot.stop_move = what; if ( what ) + { self notify( "kill_goal" ); + } } /* @@ -364,7 +384,9 @@ HasScriptGoal() SetScriptGoal( goal, dist ) { if ( !isDefined( dist ) ) + { dist = 16; + } self.bot.script_goal = goal; self.bot.script_goal_dist = dist; @@ -503,7 +525,9 @@ ClearScriptEnemy() GetThreat() { if ( !isdefined( self.bot.target ) ) + { return undefined; + } return self.bot.target.entity; } @@ -616,10 +640,14 @@ getValidTube() weap = weaps[i]; if ( !self getAmmoCount( weap ) ) + { continue; + } if ( ( isSubStr( weap, "gl_" ) && !isSubStr( weap, "_gl_" ) ) || weap == "m79_mp" ) + { return weap; + } } return undefined; @@ -671,7 +699,9 @@ waittill_either_return_( str1, str2 ) waittill_either_return( str1, str2 ) { if ( !isDefined( self waittill_either_return_( str1, str2 ) ) ) + { return str1; + } return str2; } @@ -694,10 +724,14 @@ getValidGrenade() for ( i = 0; i < grenadeTypes.size; i++ ) { if ( !self hasWeapon( grenadeTypes[i] ) ) + { continue; + } if ( !self getAmmoCount( grenadeTypes[i] ) ) + { continue; + } possibles[possibles.size] = grenadeTypes[i]; } @@ -767,7 +801,9 @@ getBotToKick() bots = getBotArray(); if ( !isDefined( bots ) || !isDefined( bots.size ) || bots.size <= 0 || !isDefined( bots[0] ) ) + { return undefined; + } tokick = undefined; axis = 0; @@ -780,14 +816,22 @@ getBotToKick() bot = bots[i]; if ( !isDefined( bot ) || !isDefined( bot.team ) ) + { continue; + } if ( bot.team == "allies" ) + { allies++; + } else if ( bot.team == "axis" ) + { axis++; + } else // choose bots that are not on a team first + { return bot; + } } // search for a bot on the other team @@ -801,7 +845,9 @@ getBotToKick() team = "allies"; if ( axis > allies ) + { team = "axis"; + } } else { @@ -814,22 +860,32 @@ getBotToKick() bot = bots[i]; if ( !isDefined( bot ) || !isDefined( bot.team ) ) + { continue; + } if ( bot.team != team ) + { continue; + } 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"] ) + { continue; + } tokick = bot; } if ( isDefined( tokick ) ) + { return tokick; + } // just kick lowest skill for ( i = 0; i < bots.size; i++ ) @@ -837,13 +893,19 @@ getBotToKick() bot = bots[i]; if ( !isDefined( bot ) || !isDefined( bot.team ) ) + { continue; + } 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"] ) + { continue; + } tokick = bot; } @@ -861,7 +923,9 @@ GetHostPlayer() player = level.players[i]; if ( !player is_host() ) + { continue; + } return player; } @@ -877,36 +941,48 @@ bot_wait_for_host() host = undefined; while ( !isDefined( level ) || !isDefined( level.players ) ) + { wait 0.05; + } for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { host = GetHostPlayer(); if ( isDefined( host ) ) + { break; + } wait 0.05; } if ( !isDefined( host ) ) + { return; + } for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { if ( IsDefined( host.pers[ "team" ] ) ) + { break; + } wait 0.05; } if ( !IsDefined( host.pers[ "team" ] ) ) + { return; + } for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { if ( host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis" ) + { break; + } wait 0.05; } @@ -922,10 +998,14 @@ RaySphereIntersect( start, end, spherePos, radius ) r2 = radius * radius; if ( DistanceSquared( start, spherePos ) < r2 ) + { return true; + } if ( DistanceSquared( end, spherePos ) < r2 ) + { return true; + } // check if the line made by start and end intersect the sphere dp = end - start; @@ -938,7 +1018,9 @@ RaySphereIntersect( start, end, spherePos, radius ) bb4ac = b * b - 4.0 * a * c; if ( abs( a ) < 0.0001 || bb4ac < 0 ) + { return false; + } mu1 = ( 0 - b + sqrt( bb4ac ) ) / ( 2 * a ); //mu2 = (0-b - sqrt(bb4ac)) / (2 * a); @@ -951,13 +1033,17 @@ RaySphereIntersect( start, end, spherePos, radius ) // check if both intersection points far if ( DistanceSquared( start, ip1 ) > myDist/* && DistanceSquared(start, ip2) > myDist*/ ) + { return false; + } dpAngles = VectorToAngles( dp ); // check if the point is behind us if ( getConeDot( ip1, start, dpAngles ) < 0/* || getConeDot(ip2, start, dpAngles) < 0*/ ) + { return false; + } return true; } @@ -972,10 +1058,14 @@ SmokeTrace( start, end, rad ) nade = level.bots_smokeList.data[i]; if ( nade.state != "smoking" ) + { continue; + } if ( !RaySphereIntersect( start, end, nade.origin, rad ) ) + { continue; + } return false; } @@ -1014,12 +1104,18 @@ Round( x ) if ( abs( x ) - abs( y ) > 0.5 ) { if ( x < 0 ) + { return y - 1; + } else + { return y + 1; + } } else + { return y; + } } /* @@ -1056,7 +1152,9 @@ parseTokensIntoWaypoint( tokens ) waypoint.children = []; for ( j = 0; j < childToks.size; j++ ) + { waypoint.children[j] = int( childToks[j] ); + } type = tokens[2]; waypoint.type = type; @@ -1103,7 +1201,9 @@ getWaypointLinesFromFile( filename ) // If the file is empty or not defined, return the empty result structure. if ( !isDefined( waypointStr ) ) + { return result; + } // Variables to track the current line's character count and starting position. linecount = 0; @@ -1120,7 +1220,9 @@ getWaypointLinesFromFile( filename ) // If the newline is '\r\n', skip the next character. if ( waypointStr[i] == "\r" && i < waypointStr.size - 1 && waypointStr[i + 1] == "\n" ) + { i++; + } // Reset linecount and update linestart for the next line. linecount = 0; @@ -1148,12 +1250,16 @@ readWpsFromFile( mapname ) filename = "waypoints/" + mapname + "_wp.csv"; if ( !BotBuiltinFileExists( filename ) ) + { return waypoints; + } res = getWaypointLinesFromFile( filename ); if ( !res.lines.size ) + { return waypoints; + } BotBuiltinPrintConsole( "Attempting to read waypoints from " + filename ); @@ -1182,7 +1288,9 @@ load_waypoints() level.waypointUsage["axis"] = []; if ( !isDefined( level.waypoints ) ) + { level.waypoints = []; + } mapname = getDvar( "mapname" ); @@ -1203,7 +1311,9 @@ load_waypoints() } if ( level.waypoints.size ) + { BotBuiltinPrintConsole( "Loaded " + level.waypoints.size + " waypoints from script" ); + } } if ( !level.waypoints.size ) @@ -1216,13 +1326,19 @@ load_waypoints() for ( i = 0; i < level.waypointCount; i++ ) { if ( !isDefined( level.waypoints[i].children ) || !isDefined( level.waypoints[i].children.size ) ) + { level.waypoints[i].children = []; + } if ( !isDefined( level.waypoints[i].origin ) ) + { level.waypoints[i].origin = ( 0, 0, 0 ); + } if ( !isDefined( level.waypoints[i].type ) ) + { level.waypoints[i].type = "crouch"; + } level.waypoints[i].childCount = undefined; } @@ -1240,7 +1356,9 @@ nearAnyOfWaypoints( dist, waypoints ) waypoint = level.waypoints[waypoints[i]]; if ( DistanceSquared( waypoint.origin, self.origin ) > dist ) + { continue; + } return true; } @@ -1262,7 +1380,9 @@ waypointsNear( waypoints, dist ) wp = level.waypoints[waypoints[i]]; if ( DistanceSquared( wp.origin, self.origin ) > dist ) + { continue; + } answer[answer.size] = waypoints[i]; } @@ -1284,7 +1404,9 @@ getNearestWaypointOfWaypoints( waypoints ) thisDist = DistanceSquared( self.origin, waypoint.origin ); if ( isDefined( answer ) && thisDist > closestDist ) + { continue; + } answer = waypoints[i]; closestDist = thisDist; @@ -1307,13 +1429,19 @@ getWaypointsOfType( type ) if ( type == "camp" ) { if ( wp.type != "crouch" ) + { continue; + } if ( wp.children.size != 1 ) + { continue; + } } else if ( type != wp.type ) + { continue; + } answer[answer.size] = i; } @@ -1327,7 +1455,9 @@ getWaypointsOfType( type ) getWaypointForIndex( i ) { if ( !isDefined( i ) ) + { return undefined; + } return level.waypoints[i]; } @@ -1580,9 +1710,13 @@ getGoodMapAmount() case "dc_whitehouse": case "mp_shipment": if ( level.teambased ) + { return 8; + } else + { return 4; + } case "mp_vacant": case "mp_terminal": @@ -1596,9 +1730,13 @@ getGoodMapAmount() case "mp_shipment_long": case "mp_rust_long": if ( level.teambased ) + { return 12; + } else + { return 8; + } case "mp_afghan": case "mp_crash": @@ -1627,17 +1765,25 @@ getGoodMapAmount() case "mp_estate_tropical": case "mp_bloc_sh": if ( level.teambased ) + { return 14; + } else + { return 9; + } case "mp_fuel2": case "mp_invasion": case "mp_derail": if ( level.teambased ) + { return 16; + } else + { return 10; + } default: return 2; @@ -1782,7 +1928,9 @@ getBotArray() player = level.players[i]; if ( !player is_bot() ) + { continue; + } result[result.size] = player; } @@ -1808,7 +1956,9 @@ WaypointsToKDTree() _WaypointsToKDTree( waypoints, dem ) { if ( !waypoints.size ) + { return; + } callbacksort = undefined; @@ -1848,10 +1998,16 @@ _WaypointsToKDTree( waypoints, dem ) right = []; for ( i = 0; i < sorted.size; i++ ) + { if ( i < median ) + { right[right.size] = sorted[i]; + } else if ( i > median ) + { left[left.size] = sorted[i]; + } + } self KDTreeInsert( sorted[median] ); @@ -1965,25 +2121,37 @@ _KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 ) { case 0: if ( data.origin[0] < node.data.origin[0] ) + { node.left = self _KDTreeInsert( node.left, data, 1, x0, y0, z0, node.data.origin[0], y1, z1 ); + } else + { node.right = self _KDTreeInsert( node.right, data, 1, node.data.origin[0], y0, z0, x1, y1, z1 ); + } break; case 1: if ( data.origin[1] < node.data.origin[1] ) + { node.left = self _KDTreeInsert( node.left, data, 2, x0, y0, z0, x1, node.data.origin[1], z1 ); + } else + { node.right = self _KDTreeInsert( node.right, data, 2, x0, node.data.origin[1], z0, x1, y1, z1 ); + } break; case 2: if ( data.origin[2] < node.data.origin[2] ) + { node.left = self _KDTreeInsert( node.left, data, 0, x0, y0, z0, x1, y1, node.data.origin[2] ); + } else + { node.right = self _KDTreeInsert( node.right, data, 0, x0, y0, node.data.origin[2], x1, y1, z1 ); + } break; } @@ -1997,7 +2165,9 @@ _KDTreeInsert( node, data, dem, x0, y0, z0, x1, y1, z1 ) KDTreeNearest( origin ) { if ( !isDefined( self.root ) ) + { return undefined; + } return self _KDTreeNearest( self.root, origin, self.root.data, DistanceSquared( self.root.data.origin, origin ), 0 ); } @@ -2049,20 +2219,32 @@ RectDistanceSquared( origin ) dz = 0; if ( origin[0] < self.x0 ) + { dx = origin[0] - self.x0; + } else if ( origin[0] > self.x1 ) + { dx = origin[0] - self.x1; + } if ( origin[1] < self.y0 ) + { dy = origin[1] - self.y0; + } else if ( origin[1] > self.y1 ) + { dy = origin[1] - self.y1; + } if ( origin[2] < self.z0 ) + { dz = origin[2] - self.z0; + } else if ( origin[2] > self.z1 ) + { dz = origin[2] - self.z1; + } return dx * dx + dy * dy + dz * dz; } @@ -2151,7 +2333,9 @@ HeapInsert( item ) current = int( current / 2 ); if ( ![[self.compare]]( item, self.data[current - 1] ) ) + { break; + } self.data[last - 1] = self.data[current - 1]; self.data[current - 1] = item; @@ -2167,15 +2351,23 @@ _HeapNextChild( node, hsize ) right = left + 1; if ( left > hsize ) + { return -1; + } if ( right > hsize ) + { return left; + } if ( [[self.compare]]( self.data[left - 1], self.data[right - 1] ) ) + { return left; + } else + { return right; + } } /* @@ -2186,7 +2378,9 @@ HeapRemove() remove = self.data.size; if ( !remove ) + { return remove; + } move = self.data[remove - 1]; self.data[0] = move; @@ -2194,7 +2388,9 @@ HeapRemove() remove--; if ( !remove ) + { return remove; + } last = 1; next = self _HeapNextChild( 1, remove ); @@ -2202,7 +2398,9 @@ HeapRemove() while ( next != -1 ) { if ( [[self.compare]]( move, self.data[next - 1] ) ) + { break; + } self.data[last - 1] = self.data[next - 1]; self.data[next - 1] = move; @@ -2228,15 +2426,21 @@ ReverseHeapAStar( item, item2 ) RemoveWaypointUsage( wp, team ) { if ( !isDefined( level.waypointUsage ) ) + { return; + } if ( !isDefined( level.waypointUsage[team][wp + ""] ) ) + { return; + } level.waypointUsage[team][wp + ""]--; if ( level.waypointUsage[team][wp + ""] <= 0 ) + { level.waypointUsage[team][wp + ""] = undefined; + } } /* @@ -2250,12 +2454,16 @@ GetNearestWaypointWithSight( pos ) for ( i = 0; i < level.waypointCount; i++ ) { if ( !bulletTracePassed( pos + ( 0, 0, 15 ), level.waypoints[i].origin + ( 0, 0, 15 ), false, undefined ) ) + { continue; + } curdis = DistanceSquared( level.waypoints[i].origin, pos ); if ( curdis > dist ) + { continue; + } dist = curdis; candidate = i; @@ -2277,7 +2485,9 @@ GetNearestWaypoint( pos ) curdis = DistanceSquared( level.waypoints[i].origin, pos ); if ( curdis > dist ) + { continue; + } dist = curdis; candidate = i; @@ -2301,29 +2511,41 @@ AStarSearch( start, goal, team, greedy_path ) startWp = getNearestWaypoint( start ); if ( !isDefined( startWp ) ) + { return []; + } _startwp = undefined; if ( !bulletTracePassed( start + ( 0, 0, 15 ), level.waypoints[startWp].origin + ( 0, 0, 15 ), false, undefined ) ) + { _startwp = GetNearestWaypointWithSight( start ); + } if ( isDefined( _startwp ) ) + { startWp = _startwp; + } goalWp = getNearestWaypoint( goal ); if ( !isDefined( goalWp ) ) + { return []; + } _goalWp = undefined; if ( !bulletTracePassed( goal + ( 0, 0, 15 ), level.waypoints[goalWp].origin + ( 0, 0, 15 ), false, undefined ) ) + { _goalwp = GetNearestWaypointWithSight( goal ); + } if ( isDefined( _goalwp ) ) + { goalWp = _goalwp; + } node = spawnStruct(); @@ -2356,7 +2578,9 @@ AStarSearch( start, goal, team, greedy_path ) if ( isdefined( team ) && isDefined( level.waypointUsage ) ) { if ( !isDefined( level.waypointUsage[team][bestNode.index + ""] ) ) + { level.waypointUsage[team][bestNode.index + ""] = 0; + } level.waypointUsage[team][bestNode.index + ""]++; } @@ -2383,15 +2607,21 @@ AStarSearch( start, goal, team, greedy_path ) temppen = 1; if ( isDefined( level.waypointUsage[team][child + ""] ) ) + { temppen = level.waypointUsage[team][child + ""]; //consider how many bots are taking this path + } if ( temppen > 1 ) + { penalty = temppen; + } } // have certain types of nodes more expensive if ( childWp.type == "climb" || childWp.type == "prone" ) + { penalty += 4; + } //calc the total path we have took newg = bestNode.g + DistanceSquared( wp.origin, childWp.origin ) * penalty; //bots on same team's path are more expensive @@ -2400,21 +2630,31 @@ AStarSearch( start, goal, team, greedy_path ) inopen = isDefined( openset[child + ""] ); if ( inopen && openset[child + ""].g <= newg ) + { continue; + } inclosed = isDefined( closed[child + ""] ); if ( inclosed && closed[child + ""].g <= newg ) + { continue; + } node = undefined; if ( inopen ) + { node = openset[child + ""]; + } else if ( inclosed ) + { node = closed[child + ""]; + } else + { node = spawnStruct(); + } node.parent = bestNode; node.g = newg; @@ -2424,7 +2664,9 @@ AStarSearch( start, goal, team, greedy_path ) //check if in closed, remove it if ( inclosed ) + { closed[child + ""] = undefined; + } //check if not in open, add it if ( !inopen ) @@ -2532,7 +2774,9 @@ onUsePlantObjectFix( player ) for ( index = 0; index < level.bombZones.size; index++ ) { if ( level.bombZones[index] == self ) + { continue; + } level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject(); } @@ -2585,7 +2829,9 @@ bombPlantedFix( destroyedObj, player ) for ( index = 0; index < level.players.size; index++ ) { if ( isDefined( level.players[index].carryIcon ) ) + { level.players[index].carryIcon destroyElem(); + } } trace = bulletTrace( player.origin + ( 0, 0, 20 ), player.origin - ( 0, 0, 2000 ), false, player ); @@ -2638,7 +2884,9 @@ bombPlantedFix( destroyedObj, player ) destroyedObj.visuals[0] maps\mp\gametypes\_gamelogic::stopTickingSound(); if ( level.gameEnded || level.bombDefused ) + { return; + } level.bombExploded = true; @@ -2651,7 +2899,9 @@ bombPlantedFix( destroyedObj, player ) player incPlayerStat( "targetsdestroyed", 1 ); } else + { destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20 ); + } rot = randomfloat( 360 ); explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + ( 0, 0, 50 ), ( 0, 0, 1 ), ( cos( rot ), sin( rot ), 0 ) ); @@ -2663,10 +2913,14 @@ bombPlantedFix( destroyedObj, player ) thread playSoundinSpace( "exp_suitcase_bomb_main", explosionOrigin ); if ( isDefined( destroyedObj.exploderIndex ) ) + { exploder( destroyedObj.exploderIndex ); + } for ( index = 0; index < level.bombZones.size; index++ ) + { level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject(); + } defuseObject maps\mp\gametypes\_gameobjects::disableObject(); @@ -2693,7 +2947,9 @@ botGiveLoadout( team, class, allowCopycat ) self.specialty = []; if ( !isDefined( allowCopycat ) ) + { allowCopycat = true; + } primaryWeapon = undefined; @@ -2769,7 +3025,9 @@ botGiveLoadout( team, class, allowCopycat ) } if ( loadoutPerk1 != "specialty_onemanarmy" && loadoutSecondary == "onemanarmy" ) + { loadoutSecondary = maps\mp\gametypes\_class::table_getWeapon( level.classTableName, 10, 1 ); + } //loadoutSecondaryCamo = "none"; @@ -2781,19 +3039,29 @@ botGiveLoadout( team, class, allowCopycat ) loadoutDeathstreak = "specialty_null"; if ( loadoutPrimary == "riotshield" ) + { loadoutPrimary = "m4"; + } if ( loadoutSecondary == "at4" ) + { loadoutSecondary = "usp"; + } if ( loadoutPrimaryAttachment == "gl" ) + { loadoutPrimaryAttachment = "none"; + } if ( loadoutPerk2 == "specialty_coldblooded" ) + { loadoutPerk2 = "specialty_null"; + } if ( loadoutPerk3 == "specialty_localjammer" ) + { loadoutPerk3 = "specialty_null"; + } } @@ -2842,7 +3110,9 @@ botGiveLoadout( team, class, allowCopycat ) // these special case giving pistol death have to come before // perk loadout to ensure player perk icons arent overwritten if ( level.dieHardMode ) + { self maps\mp\perks\_perks::givePerk( "specialty_pistoldeath" ); + } // only give the deathstreak for the initial spawn for this life. if ( loadoutDeathStreak != "specialty_null" && ( getTime() - self.spawnTime ) < 0.1 ) @@ -2850,7 +3120,9 @@ botGiveLoadout( team, class, allowCopycat ) deathVal = int( tableLookup( "mp/perkTable.csv", 1, loadoutDeathStreak, 6 ) ); if ( self botGetPerkUpgrade( loadoutPerk1 ) == "specialty_rollover" || self botGetPerkUpgrade( loadoutPerk2 ) == "specialty_rollover" || self botGetPerkUpgrade( loadoutPerk3 ) == "specialty_rollover" ) + { deathVal -= 1; + } if ( self.pers["cur_death_streak"] == deathVal ) { @@ -2868,7 +3140,9 @@ botGiveLoadout( team, class, allowCopycat ) self maps\mp\gametypes\_class::setKillstreaks( loadoutKillstreak1, loadoutKillstreak2, loadoutKillstreak3 ); if ( self hasPerk( "specialty_extraammo", true ) && getWeaponClass( secondaryName ) != "weapon_projectile" ) + { self giveMaxAmmo( secondaryName ); + } // Primary Weapon primaryName = maps\mp\gametypes\_class::buildWeaponName( loadoutPrimary, loadoutPrimaryAttachment, loadoutPrimaryAttachment2 ); @@ -2876,10 +3150,14 @@ botGiveLoadout( team, class, allowCopycat ) // fix changing from a riotshield class to a riotshield class during grace period not giving a shield if ( primaryName == "riotshield_mp" && level.inGracePeriod ) + { self notify ( "weapon_change", "riotshield_mp" ); + } if ( self hasPerk( "specialty_extraammo", true ) ) + { self giveMaxAmmo( primaryName ); + } self setSpawnWeapon( primaryName ); @@ -2892,20 +3170,32 @@ botGiveLoadout( team, class, allowCopycat ) offhandSecondaryWeapon = loadoutOffhand + "_mp"; if ( loadoutOffhand == "flash_grenade" ) + { self SetOffhandSecondaryClass( "flash" ); + } else + { self SetOffhandSecondaryClass( "smoke" ); + } self giveWeapon( offhandSecondaryWeapon ); if ( loadOutOffhand == "smoke_grenade" ) + { self setWeaponAmmoClip( offhandSecondaryWeapon, 1 ); + } else if ( loadOutOffhand == "flash_grenade" ) + { self setWeaponAmmoClip( offhandSecondaryWeapon, 2 ); + } else if ( loadOutOffhand == "concussion_grenade" ) + { self setWeaponAmmoClip( offhandSecondaryWeapon, 2 ); + } else + { self setWeaponAmmoClip( offhandSecondaryWeapon, 1 ); + } primaryWeapon = primaryName; self.primaryWeapon = primaryWeapon; @@ -2932,10 +3222,14 @@ botGetPerkUpgrade( perkName ) perkUpgrade = tablelookup( "mp/perktable.csv", 1, perkName, 8 ); if ( perkUpgrade == "" || perkUpgrade == "specialty_null" ) + { return "specialty_null"; + } if ( !isDefined( self.pers["bots"]["unlocks"]["upgraded_" + perkName] ) || !self.pers["bots"]["unlocks"]["upgraded_" + perkName] ) + { return "specialty_null"; + } return ( perkUpgrade ); } @@ -2969,10 +3263,14 @@ botLoadoutAllPerks( loadoutEquipment, loadoutPerk1, loadoutPerk2, loadoutPerk3 ) perk = perks[i]; if ( upgrade == "" || upgrade == "specialty_null" ) + { continue; + } if ( isDefined( self.pers["bots"]["unlocks"]["upgraded_" + perk] ) && self.pers["bots"]["unlocks"]["upgraded_" + perk] ) + { self maps\mp\perks\_perks::givePerk( upgrade ); + } } } @@ -3004,17 +3302,25 @@ botPlayerModelForWeapon( weapon, secondary ) weaponClass = tablelookup( "mp/statstable.csv", 4, secondary, 2 ); if ( weaponClass == "weapon_shotgun" ) + { [[game[team + "_model"]["SHOTGUN"]]](); + } else + { [[game[team + "_model"]["ASSAULT"]]](); + } break; case "weapon_sniper": if ( level.environment != "" && isDefined( self.pers["bots"]["unlocks"]["ghillie"] ) && self.pers["bots"]["unlocks"]["ghillie"] ) + { [[game[team + "_model"]["GHILLIE"]]](); + } else + { [[game[team + "_model"]["SNIPER"]]](); + } break; diff --git a/maps/mp/bots/_menu.gsc b/maps/mp/bots/_menu.gsc index d440ebb..4fb51f5 100644 --- a/maps/mp/bots/_menu.gsc +++ b/maps/mp/bots/_menu.gsc @@ -13,10 +13,14 @@ init() { if ( getDvar( "bots_main_menu" ) == "" ) + { setDvar( "bots_main_menu", true ); + } if ( !getDvarInt( "bots_main_menu" ) ) + { return; + } thread watchPlayers(); } @@ -28,17 +32,23 @@ watchPlayers() wait 1; if ( !getDvarInt( "bots_main_menu" ) ) + { return; + } for ( i = level.players.size - 1; i >= 0; i-- ) { player = level.players[i]; if ( !player is_host() ) + { continue; + } if ( isDefined( player.menuInit ) && player.menuInit ) + { continue; + } player thread init_menu(); } @@ -80,26 +90,44 @@ watchDisconnect() if ( self.menuOpen ) { if ( isDefined( self.MenuTextY ) ) + { for ( i = 0; i < self.MenuTextY.size; i++ ) + { if ( isDefined( self.MenuTextY[i] ) ) + { self.MenuTextY[i] destroy(); + } + } + } if ( isDefined( self.MenuText ) ) + { for ( i = 0; i < self.MenuText.size; i++ ) + { if ( isDefined( self.MenuText[i] ) ) + { self.MenuText[i] destroy(); + } + } + } if ( isDefined( self.Menu ) && isDefined( self.Menu["X"] ) ) { if ( isDefined( self.Menu["X"]["Shader"] ) ) + { self.Menu["X"]["Shader"] destroy(); + } if ( isDefined( self.Menu["X"]["Scroller"] ) ) + { self.Menu["X"]["Scroller"] destroy(); + } } if ( isDefined( self.menuVersionHud ) ) + { self.menuVersionHud destroy(); + } } } @@ -134,15 +162,21 @@ watchPlayerOpenMenu() self playLocalSound( "mouse_click" ); if ( self.SubMenu != "Main" ) + { self ExitSub(); + } else { self ExitMenu(); if ( !gameFlag( "prematch_done" ) || level.gameEnded ) + { self freezeControls( true ); + } else + { self freezecontrols( false ); + } } } } @@ -164,9 +198,13 @@ MenuSelect() self playLocalSound( "mouse_click" ); if ( self.SubMenu == "Main" ) + { self thread [[self.Option["Function"][self.SubMenu][self.Curs["Main"]["X"]]]]( self.Option["Arg1"][self.SubMenu][self.Curs["Main"]["X"]], self.Option["Arg2"][self.SubMenu][self.Curs["Main"]["X"]] ); + } else + { self thread [[self.Option["Function"][self.SubMenu][self.Curs[self.SubMenu]["Y"]]]]( self.Option["Arg1"][self.SubMenu][self.Curs[self.SubMenu]["Y"]], self.Option["Arg2"][self.SubMenu][self.Curs[self.SubMenu]["Y"]] ); + } } } } @@ -188,7 +226,9 @@ LeftMenu() self.Curs["Main"]["X"]--; if ( self.Curs["Main"]["X"] < 0 ) + { self.Curs["Main"]["X"] = self.Option["Name"][self.SubMenu].size - 1; + } self CursMove( "X" ); } @@ -212,7 +252,9 @@ RightMenu() self.Curs["Main"]["X"]++; if ( self.Curs["Main"]["X"] > self.Option["Name"][self.SubMenu].size - 1 ) + { self.Curs["Main"]["X"] = 0; + } self CursMove( "X" ); } @@ -236,7 +278,9 @@ UpMenu() self.Curs[self.SubMenu]["Y"]--; if ( self.Curs[self.SubMenu]["Y"] < 0 ) + { self.Curs[self.SubMenu]["Y"] = self.Option["Name"][self.SubMenu].size - 1; + } self CursMove( "Y" ); } @@ -260,7 +304,9 @@ DownMenu() self.Curs[self.SubMenu]["Y"]++; if ( self.Curs[self.SubMenu]["Y"] > self.Option["Name"][self.SubMenu].size - 1 ) + { self.Curs[self.SubMenu]["Y"] = 0; + } self CursMove( "Y" ); } @@ -281,21 +327,33 @@ OpenSub( menu, menu2 ) if ( self.SubMenu == "Main" ) { if ( isDefined( self.MenuText ) ) + { for ( i = 0; i < self.MenuText.size; i++ ) + { if ( isDefined( self.MenuText[i] ) ) + { self.MenuText[i] destroy(); + } + } + } if ( isDefined( self.Menu ) && isDefined( self.Menu["X"] ) ) { if ( isDefined( self.Menu["X"]["Shader"] ) ) + { self.Menu["X"]["Shader"] destroy(); + } if ( isDefined( self.Menu["X"]["Scroller"] ) ) + { self.Menu["X"]["Scroller"] destroy(); + } } if ( isDefined( self.menuVersionHud ) ) + { self.menuVersionHud destroy(); + } for ( i = 0 ; i < self.Option["Name"][self.SubMenu].size ; i++ ) { @@ -304,7 +362,9 @@ OpenSub( menu, menu2 ) self.MenuText[i] settext( self.Option["Name"][self.SubMenu][i] ); if ( logOldi ) + { self.oldi = i; + } if ( self.MenuText[i].x > 300 ) { @@ -318,9 +378,13 @@ OpenSub( menu, menu2 ) } if ( !logOldi ) + { self.Menu["X"]["Shader"] = self createRectangle( "CENTER", "CENTER", 0, -225, 1000, 90, ( 0, 0, 0 ), -2, 1, "white" ); + } else + { self.Menu["X"]["Shader"] = self createRectangle( "CENTER", "CENTER", 0, -225, 1000, 30, ( 0, 0, 0 ), -2, 1, "white" ); + } self.Menu["X"]["Scroller"] = self createRectangle( "CENTER", "CENTER", self.MenuText[self.Curs["Main"]["X"]].x, -225, 105, 22, ( 1, 0, 0 ), -1, 1, "white" ); @@ -333,9 +397,15 @@ OpenSub( menu, menu2 ) else { if ( isDefined( self.MenuTextY ) ) + { for ( i = 0 ; i < self.MenuTextY.size ; i++ ) + { if ( isDefined( self.MenuTextY[i] ) ) + { self.MenuTextY[i] destroy(); + } + } + } for ( i = 0 ; i < self.Option["Name"][self.SubMenu].size ; i++ ) { @@ -416,9 +486,13 @@ ShowOptionOn( variable ) for ( time = 0;; time += 0.05 ) { if ( !self isOnGround() && isAlive( self ) && gameFlag( "prematch_done" ) && !level.gameEnded ) + { self freezecontrols( false ); + } else + { self freezecontrols( true ); + } self setClientDvar( "r_blur", "5" ); self setClientDvar( "sc_blur", "15" ); @@ -433,7 +507,9 @@ ShowOptionOn( variable ) color = ( 6 / 255, 69 / 255, 173 + randomIntRange( -5, 5 ) / 255 ); if ( int( time * 4 ) % 2 ) + { color = ( 11 / 255, 0 / 255, 128 + randomIntRange( -10, 10 ) / 255 ); + } self.MenuText[self.Curs[self.SubMenu][variable]].color = color; } @@ -443,7 +519,9 @@ ShowOptionOn( variable ) for ( i = 0; i < self.Option["Name"][self.SubMenu].size; i++ ) { if ( isDefined( self.MenuText[i] ) ) + { self.MenuText[i] settext( self.Option["Name"][self.SubMenu][i] ); + } } } } @@ -456,7 +534,9 @@ ShowOptionOn( variable ) color = ( 6 / 255, 69 / 255, 173 + randomIntRange( -5, 5 ) / 255 ); if ( int( time * 4 ) % 2 ) + { color = ( 11 / 255, 0 / 255, 128 + randomIntRange( -10, 10 ) / 255 ); + } self.MenuTextY[self.Curs[self.SubMenu][variable]].color = color; } @@ -466,7 +546,9 @@ ShowOptionOn( variable ) for ( i = 0; i < self.Option["Name"][self.SubMenu].size; i++ ) { if ( isDefined( self.MenuTextY[i] ) ) + { self.MenuTextY[i] settext( self.Option["Name"][self.SubMenu][i] ); + } } } } @@ -491,36 +573,58 @@ AddBack( menu, back ) ExitSub() { if ( isDefined( self.MenuTextY ) ) + { for ( i = 0; i < self.MenuTextY.size; i++ ) + { if ( isDefined( self.MenuTextY[i] ) ) + { self.MenuTextY[i] destroy(); + } + } + } self.SubMenu = self.Menu["Back"][self.Submenu]; if ( self.SubMenu == "Main" ) + { self CursMove( "X" ); + } else + { self CursMove( "Y" ); + } } ExitMenu() { if ( isDefined( self.MenuText ) ) + { for ( i = 0; i < self.MenuText.size; i++ ) + { if ( isDefined( self.MenuText[i] ) ) + { self.MenuText[i] destroy(); + } + } + } if ( isDefined( self.Menu ) && isDefined( self.Menu["X"] ) ) { if ( isDefined( self.Menu["X"]["Shader"] ) ) + { self.Menu["X"]["Shader"] destroy(); + } if ( isDefined( self.Menu["X"]["Scroller"] ) ) + { self.Menu["X"]["Scroller"] destroy(); + } } if ( isDefined( self.menuVersionHud ) ) + { self.menuVersionHud destroy(); + } self.MenuOpen = false; self notify( "exit" ); @@ -590,9 +694,13 @@ AddOptions() _tempDvar = getDvarInt( "bots_manage_fill_kick" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "man_bots", 7, "Toggle auto bot kicking: " + _temp, ::man_bots, "autokick", _tempDvar ); @@ -634,9 +742,13 @@ AddOptions() _tempDvar = getDvarInt( "bots_manage_fill_spec" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "man_bots", 11, "Count players for fill on spectator: " + _temp, ::man_bots, "fillspec", _tempDvar ); @@ -655,18 +767,26 @@ AddOptions() _tempDvar = getDvarInt( "bots_team_force" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "man_team", 3, "Toggle forcing bots on team: " + _temp, ::bot_teams, "teamforce", _tempDvar ); _tempDvar = getDvarInt( "bots_team_mode" ); if ( _tempDvar ) + { _temp = "only bots"; + } else + { _temp = "everyone"; + } self AddMenu( "man_team", 4, "Toggle bot_team_bot: " + _temp, ::bot_teams, "teammode", _tempDvar ); @@ -745,117 +865,169 @@ AddOptions() _tempDvar = getDvarInt( "bots_loadout_reasonable" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 0, "Bots use only good class setups: " + _temp, ::bot_func, "reasonable", _tempDvar ); _tempDvar = getDvarInt( "bots_loadout_allow_op" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 1, "Bots can use op and annoying class setups: " + _temp, ::bot_func, "op", _tempDvar ); _tempDvar = getDvarInt( "bots_play_move" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 2, "Bots can move: " + _temp, ::bot_func, "move", _tempDvar ); _tempDvar = getDvarInt( "bots_play_knife" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 3, "Bots can knife: " + _temp, ::bot_func, "knife", _tempDvar ); _tempDvar = getDvarInt( "bots_play_fire" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 4, "Bots can fire: " + _temp, ::bot_func, "fire", _tempDvar ); _tempDvar = getDvarInt( "bots_play_nade" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 5, "Bots can nade: " + _temp, ::bot_func, "nade", _tempDvar ); _tempDvar = getDvarInt( "bots_play_take_carepackages" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 6, "Bots can take carepackages: " + _temp, ::bot_func, "care", _tempDvar ); _tempDvar = getDvarInt( "bots_play_obj" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 7, "Bots play the objective: " + _temp, ::bot_func, "obj", _tempDvar ); _tempDvar = getDvarInt( "bots_play_camp" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 8, "Bots can camp: " + _temp, ::bot_func, "camp", _tempDvar ); _tempDvar = getDvarInt( "bots_play_jumpdrop" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 9, "Bots can jump and dropshot: " + _temp, ::bot_func, "jump", _tempDvar ); _tempDvar = getDvarInt( "bots_play_target_other" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 10, "Bots can target other script objects: " + _temp, ::bot_func, "targetother", _tempDvar ); _tempDvar = getDvarInt( "bots_play_killstreak" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 11, "Bots can use killstreaks: " + _temp, ::bot_func, "killstreak", _tempDvar ); _tempDvar = getDvarInt( "bots_play_ads" ); if ( _tempDvar ) + { _temp = "true"; + } else + { _temp = "false"; + } self AddMenu( "set1", 12, "Bots can ads: " + _temp, ::bot_func, "ads", _tempDvar ); } @@ -1114,7 +1286,9 @@ man_bots( a, b ) } if ( !result ) + { self iPrintln( "No bots to kick" ); + } break; diff --git a/maps/mp/bots/_wp_editor.gsc b/maps/mp/bots/_wp_editor.gsc index 44c708c..2471214 100644 --- a/maps/mp/bots/_wp_editor.gsc +++ b/maps/mp/bots/_wp_editor.gsc @@ -13,10 +13,14 @@ init() { if ( getDvar( "bots_main_debug" ) == "" ) + { setDvar( "bots_main_debug", 0 ); + } if ( !getDVarint( "bots_main_debug" ) ) + { return; + } if ( !getDVarint( "developer" ) ) { @@ -36,16 +40,24 @@ init() setDvar( "bots_manage_fill_spec", 1 ); 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_minDist" ) == "" ) + { setDvar( "bots_main_debug_minDist", 32.0 ); + } if ( getDvar( "bots_main_debug_drawThrough" ) == "" ) + { setDvar( "bots_main_debug_drawThrough", false ); + } setDvar( "player_sustainAmmo", 1 ); @@ -131,7 +143,9 @@ watchAstarCommand() self waittill( "astar" ); if ( 1 ) + { continue; + } self iprintln( "Start AStar" ); self.astar = undefined; @@ -182,23 +196,33 @@ updateWaypointsStats() 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" ) && ( bulletTracePassed( myEye, wpOrg, false, self ) || getDVarint( "bots_main_debug_drawThrough" ) ) ) { for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- ) + { line( wpOrg, level.waypoints[level.waypoints[i].children[h]].origin + ( 0, 0, 25 ), ( 1, 0, 1 ) ); + } if ( getConeDot( wpOrg, myEye, myAngles ) > getDvarFloat( "bots_main_debug_cone" ) ) + { print3d( wpOrg, i, ( 1, 0, 0 ), 2 ); + } if ( isDefined( level.waypoints[i].angles ) && level.waypoints[i].type != "stand" ) + { line( wpOrg, wpOrg + AnglesToForward( level.waypoints[i].angles ) * 64, ( 1, 1, 1 ) ); + } if ( isDefined( level.waypoints[i].jav_point ) ) + { line( wpOrg, level.waypoints[i].jav_point, ( 0, 0, 0 ) ); + } } } @@ -215,7 +239,9 @@ updateWaypointsStats() infotext.x = infotext.x - 2; if ( infotext.x <= -800 ) + { infotext.x = 800; + } if ( self UseButtonPressed() && time > 2 ) { @@ -386,10 +412,14 @@ watchSaveWaypointsCommand() } if ( isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) ) + { logprint( "*/waypoints[" + i + "].angles = " + level.waypoints[i].angles + ";\n/*" ); + } if ( isDefined( level.waypoints[i].jav_point ) && level.waypoints[i].type == "javelin" ) + { logprint( "*/waypoints[" + i + "].jav_point = " + level.waypoints[i].jav_point + ";\n/*" ); + } } logprint( "*/return waypoints;\n}\n\n\n\n" ); @@ -413,20 +443,30 @@ watchSaveWaypointsCommand() str += wp.children[h]; if ( h < wp.children.size - 1 ) + { str += " "; + } } str += "," + wp.type + ","; if ( isDefined( wp.angles ) ) + { str += wp.angles[0] + " " + wp.angles[1] + " " + wp.angles[2] + ","; + } else + { str += ","; + } if ( isDefined( wp.jav_point ) ) + { str += wp.jav_point[0] + " " + wp.jav_point[1] + " " + wp.jav_point[2] + ","; + } else + { str += ","; + } PrintLn( str ); BotBuiltinFileWrite( filename, str + "\n", "append" ); @@ -452,10 +492,14 @@ LoadWaypoints() checkForWarnings() { if ( level.waypointCount <= 0 ) + { self iprintln( "WARNING: waypointCount is " + level.waypointCount ); + } if ( level.waypointCount != level.waypoints.size ) + { self iprintln( "WARNING: waypointCount is not " + level.waypoints.size ); + } for ( i = 0; i < level.waypointCount; i++ ) { @@ -466,7 +510,9 @@ checkForWarnings() } if ( level.waypoints[i].children.size <= 0 ) + { self iprintln( "WARNING: waypoint " + i + " childCount is " + level.waypoints[i].children.size ); + } else { if ( !isDefined( level.waypoints[i].children ) || !isDefined( level.waypoints[i].children.size ) ) @@ -480,9 +526,13 @@ checkForWarnings() child = level.waypoints[i].children[h]; if ( !isDefined( level.waypoints[child] ) ) + { self iprintln( "WARNING: waypoint " + i + " child " + child + " is undefined" ); + } else if ( child == i ) + { self iprintln( "WARNING: waypoint " + i + " child " + child + " is itself" ); + } } } } @@ -494,10 +544,14 @@ checkForWarnings() } if ( level.waypoints[i].type == "javelin" && !isDefined( level.waypoints[i].jav_point ) ) + { self iprintln( "WARNING: waypoint " + i + " jav_point is undefined" ); + } if ( !isDefined( level.waypoints[i].angles ) && ( level.waypoints[i].type == "claymore" || level.waypoints[i].type == "tube" || ( level.waypoints[i].type == "crouch" && level.waypoints[i].children.size == 1 ) || level.waypoints[i].type == "climb" || level.waypoints[i].type == "grenade" ) ) + { self iprintln( "WARNING: waypoint " + i + " angles is undefined" ); + } } // check reachability, assume bidirectional graph @@ -507,12 +561,16 @@ checkForWarnings() for ( i = 0; i < level.waypointCount; i++ ) { if ( i % 5 == 0 ) + { wait 0.05; + } astar = AStarSearch( level.waypoints[wpIdx].origin, level.waypoints[i].origin, undefined, true ); if ( astar.size <= 0 ) + { self iprintln( "WARNING: waypoint " + wpIdx + " has no path to waypoint " + i ); + } } self iprintln( "Waypoint warnings check completed." ); @@ -620,7 +678,9 @@ DeleteWaypoint( nwp ) for ( h = level.waypoints[i].children.size - 1; h >= 0; h-- ) { if ( level.waypoints[i].children[h] > nwp ) + { level.waypoints[i].children[h]--; + } } } @@ -652,17 +712,29 @@ AddWaypoint() level.waypoints[level.waypointCount].origin = pos; if ( isDefined( self.javelinTargetPoint ) ) + { level.waypoints[level.waypointCount].type = "javelin"; + } else if ( self AdsButtonPressed() ) + { level.waypoints[level.waypointCount].type = "climb"; + } else if ( self AttackButtonPressed() && self UseButtonPressed() ) + { level.waypoints[level.waypointCount].type = "tube"; + } else if ( self AttackButtonPressed() ) + { level.waypoints[level.waypointCount].type = "grenade"; + } else if ( self UseButtonPressed() ) + { level.waypoints[level.waypointCount].type = "claymore"; + } else + { level.waypoints[level.waypointCount].type = self getStance(); + } level.waypoints[level.waypointCount].angles = self getPlayerAngles(); @@ -678,7 +750,9 @@ AddWaypoint() if ( level.autoLink ) { if ( level.wpToLink == -1 ) + { level.wpToLink = level.waypointCount - 1; + } level.waypointCount++; self LinkWaypoint( level.waypointCount - 1 ); @@ -700,7 +774,9 @@ DeleteAllWaypoints() buildChildCountString ( wp ) { if ( wp == -1 ) + { return ""; + } wpstr = level.waypoints[wp].children.size + ""; @@ -710,16 +786,22 @@ buildChildCountString ( wp ) buildChildString( wp ) { if ( wp == -1 ) + { return ""; + } wpstr = ""; for ( i = 0; i < level.waypoints[wp].children.size; i++ ) { if ( i != 0 ) + { wpstr = wpstr + "," + level.waypoints[wp].children[i]; + } else + { wpstr = wpstr + level.waypoints[wp].children[i]; + } } return wpstr; @@ -728,7 +810,9 @@ buildChildString( wp ) buildTypeString( wp ) { if ( wp == -1 ) + { return ""; + } return level.waypoints[wp].type; }