From 9713ac71b775e7705722079061d851a0ee7b5fb3 Mon Sep 17 00:00:00 2001 From: ineedbots Date: Fri, 18 Jun 2021 15:28:18 -0600 Subject: [PATCH] Format scripts --- main_shared/maps/mp/bots/_bot_loadout.gsc | 2642 +++++++++--------- main_shared/maps/mp/bots/_bot_script.gsc | 3064 +++++++++++---------- main_shared/maps/mp/bots/_bot_utility.gsc | 383 ++- main_shared/maps/mp/gametypes/_bot.gsc | 1943 ++++++------- 4 files changed, 4160 insertions(+), 3872 deletions(-) diff --git a/main_shared/maps/mp/bots/_bot_loadout.gsc b/main_shared/maps/mp/bots/_bot_loadout.gsc index 30fe162..74e37db 100644 --- a/main_shared/maps/mp/bots/_bot_loadout.gsc +++ b/main_shared/maps/mp/bots/_bot_loadout.gsc @@ -1,1294 +1,1348 @@ -/* - _bot_loadout - Author: INeedGames - Date: 12/20/2020 - Loadout stuff -*/ - -#include common_scripts\utility; -#include maps\mp\_utility; -#include maps\mp\gametypes\_hud_util; -#include maps\mp\bots\_bot_utility; - -/* - Gives the bot loadout -*/ -bot_give_loadout() -{ - self bot_giveKillstreaks(); - - self clearPerks(); - - self SetPlayerRenderOptions( int( self.pers["bot"]["class_render_opts"] ) ); - - if (!isDefined(self.bot)) - self.bot = []; - - self.bot[ "specialty1" ] = "specialty_null"; - self.bot[ "specialty2" ] = "specialty_null"; - self.bot[ "specialty3" ] = "specialty_null"; - - if (self.pers["bot"]["class_perk1"] != "" && GetDvarInt( #"scr_game_perks" ) ) - { - self.bot[ "specialty1" ] = self.pers["bot"]["class_perk1"]; - - id = bot_perk_from_reference_full(self.pers["bot"]["class_perk1"]); - tokens = strtok(id["reference"], "|"); - - for (i = 0; i < tokens.size; i++) - self setPerk(tokens[i]); - } - - switch( self.pers["bot"]["class_perk1"] ) - { - case "perk_ghost": - case "perk_ghost_pro": - self.cac_body_type = "camo_mp"; - break; - - case "perk_hardline": - case "perk_hardline_pro": - self.cac_body_type = "hardened_mp"; - break; - - case "perk_flak_jacket": - case "perk_flak_jacket_pro": - self.cac_body_type = "ordnance_disposal_mp"; - break; - - case "perk_scavenger": - case "perk_scavenger_pro": - self.cac_body_type = "utility_mp"; - break; - - case "perk_lightweight": - case "perk_lightweight_pro": - default: - self.cac_body_type = "standard_mp"; - break; - } - - self.cac_head_type = self maps\mp\gametypes\_armor::get_default_head(); - self.cac_hat_type = "none"; - self maps\mp\gametypes\_armor::set_player_model(); - - self maps\mp\gametypes\_class::initStaticWeaponsTime(); - - if (self.pers["bot"]["class_perk2"] != "" && GetDvarInt( #"scr_game_perks" )) - { - self.bot[ "specialty2" ] = self.pers["bot"]["class_perk2"]; - - id = bot_perk_from_reference_full(self.pers["bot"]["class_perk2"]); - tokens = strtok(id["reference"], "|"); - - for (i = 0; i < tokens.size; i++) - self setPerk(tokens[i]); - } - - if (self.pers["bot"]["class_perk3"] != "" && GetDvarInt( #"scr_game_perks" )) - { - self.bot[ "specialty3" ] = self.pers["bot"]["class_perk3"]; - - id = bot_perk_from_reference_full(self.pers["bot"]["class_perk3"]); - tokens = strtok(id["reference"], "|"); - - for (i = 0; i < tokens.size; i++) - self setPerk(tokens[i]); - } - - - self takeAllWeapons(); - if (getDvarInt("bots_play_knife")) - self GiveWeapon( "knife_mp" ); - - weap = self.pers["bot"]["class_primary"]; - if(weap == "") - weap = "ak47_mp"; - - primaryTokens = strtok( self.pers["bot"]["class_primary"], "_" ); - self.pers["primaryWeapon"] = primaryTokens[0]; - - weap = self.pers["bot"]["class_primary"]; - if(GetDvarInt( #"scr_disable_attachments" )) - weap = self.pers["primaryWeapon"] + "_mp"; - - self GiveWeapon( weap, 0, int( self.pers["bot"]["class_primary_opts"] ) ); - - if ( self hasPerk( "specialty_extraammo" ) ) - self giveMaxAmmo( weap ); - - if (!getDVarint("bots_play_fire")) - { - self SetWeaponAmmoClip(weap, 0); - self SetWeaponAmmoStock(weap, 0); - } - - if(self.pers["bot"]["class_secondary"] != "") - { - self GiveWeapon( self.pers["bot"]["class_secondary"], 0, int( self.pers["bot"]["class_secondary_opts"] ) ); - if ( self hasPerk( "specialty_extraammo" ) ) - self giveMaxAmmo( self.pers["bot"]["class_secondary"] ); - - if (!getDVarint("bots_play_fire")) - { - self SetWeaponAmmoClip(self.pers["bot"]["class_secondary"], 0); - self SetWeaponAmmoStock(self.pers["bot"]["class_secondary"], 0); - } - } - - self SetActionSlot( 3, "altMode" ); - self SetActionSlot( 4, "" ); - - if(self.pers["bot"]["class_equipment"] != "" && self.pers["bot"]["class_equipment"] != "weapon_null_mp" && !GetDvarInt( #"scr_disable_equipment" )) - { - self GiveWeapon( self.pers["bot"]["class_equipment"] ); - - self maps\mp\gametypes\_class::setWeaponAmmoOverall( self.pers["bot"]["class_equipment"], 1 ); - - self SetActionSlot( 1, "weapon", self.pers["bot"]["class_equipment"] ); - } - - if(self.pers["bot"]["class_lethal"] != "") - { - self GiveWeapon( self.pers["bot"]["class_lethal"] ); - - if(self hasPerk("specialty_twogrenades")) - self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 2 ); - else - self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 1 ); - - self SwitchToOffhand( self.pers["bot"]["class_lethal"] ); - } - - if(self.pers["bot"]["class_tacticle"] != "") - { - self giveWeapon( self.pers["bot"]["class_tacticle"] ); - - if(self.pers["bot"]["class_tacticle"] == "willy_pete_mp") - self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 1 ); - else if(self hasPerk("specialty_twogrenades")) - self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 3 ); - else - self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 2 ); - - self setOffhandSecondaryClass( self.pers["bot"]["class_tacticle"] ); - } - - self thread fixSecondarySwitch(weap); -} - -/* - Fixes the weapon on spawn for the bot -*/ -fixSecondarySwitch(weap) -{ - self endon("death"); - self endon("disconnect"); - self switchToWeapon(weap); - self setSpawnWeapon(weap); - wait 0.05; - self switchToWeapon(weap); - self setSpawnWeapon(weap); -} - -/* - Gets the prestige -*/ -bot_get_prestige() -{ - p_dvar = getDvarInt("bots_loadout_prestige"); - p = 0; - - if (p_dvar == -1) - { - for (i = 0; i < level.players.size; i++) - { - player = level.players[i]; - - if (!isDefined(player.team)) - continue; - - if (player is_bot()) - continue; - - p = player maps\mp\gametypes\_persistence::statGet( "plevel" ); - break; - } - } - else if (p_dvar == -2) - { - p = randomInt(17); - } - else - { - p = p_dvar; - } - - self.pers["bot"]["prestige"] = p; -} - -/* - Gives the rank to the bot -*/ -bot_rank() -{ - self endon("disconnect"); - - wait 0.05; - - self.pers["rankxp"] = self.pers["bot"]["rankxp"]; - rankId = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ); - prestige = self.pers["bot"]["prestige"]; - - self.pers["rank"] = rankId; - self.pers["prestige"] = prestige; - self.pers["plevel"] = prestige; - self setRank( rankId, prestige ); - - if(!level.gameEnded) - level waittill("game_ended"); - - self.pers["bot"]["rankxp"] = self.pers["rankxp"]; -} - -/* - Set the bot's class -*/ -bot_set_class() -{ - self.pers["bot"]["class_render_opts"] = 0; - - self.pers["bot"]["class_primary"] = ""; - self.pers["bot"]["class_primary_opts"] = 0; - self.pers["bot"]["class_secondary"] = ""; - self.pers["bot"]["class_secondary_opts"] = 0; - - self.pers["bot"]["class_lethal"] = ""; - self.pers["bot"]["class_tacticle"] = ""; - self.pers["bot"]["class_equipment"] = ""; - - self.pers["bot"]["class_perk1"] = ""; - self.pers["bot"]["class_perk2"] = ""; - self.pers["bot"]["class_perk3"] = ""; - - self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points_org" ];//refund prev payments for class - - rank = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ); - - if ( !level.onlineGame ) - { - rank = level.maxRank; - } - - if (rank < 3 || (randomint(100) < 3 && !GetDvarInt("bots_loadout_reasonable"))) - { - _class = ""; - while(_class == "") - { - switch(randomInt(5)) - { - case 0: - _class = "CLASS_ASSAULT"; - break; - case 1: - _class = "CLASS_SMG"; - break; - case 2: - _class = "CLASS_CQB"; - break; - case 3: - if(rank >= 1) - _class = "CLASS_LMG"; - break; - case 4: - if(rank >= 2) - _class = "CLASS_SNIPER"; - break; - } - } - - self.pers["bot"]["class_primary"] = level.classWeapons["axis"][_class][0]; - self.pers["bot"]["class_secondary"] = level.classSidearm["axis"][_class]; - self.pers["bot"]["class_perk1"] = level.default_perkIcon[_class][ 0 ]; - self.pers["bot"]["class_perk2"] = level.default_perkIcon[_class][ 1 ]; - self.pers["bot"]["class_perk3"] = level.default_perkIcon[_class][ 2 ]; - self.pers["bot"]["class_equipment"] = level.default_equipment[ _class ][ "type" ]; - self.pers["bot"]["class_lethal"] = level.classGrenades[_class]["primary"]["type"]; - self.pers["bot"]["class_tacticle"] = level.classGrenades[_class]["secondary"]["type"]; - } - else - { - self bot_get_random_perk("1", rank); - self bot_get_random_perk("2", rank); - self bot_get_random_perk("3", rank); - - self bot_get_random_weapon("primary", rank); - self bot_get_random_weapon("secondary", rank); - self bot_get_random_weapon("primarygrenade", rank); - self bot_get_random_weapon("specialgrenade", rank); - self bot_get_random_weapon("equipment", rank); - - if(rank >= 21) - camo = self bot_random_camo(); - else - camo = 0; - - if(rank >= 18) - tag = self bot_random_tag(); - else - tag = 0; - - if(rank >= 15) - emblem = self bot_random_emblem(); - else - emblem = 0; - - if(isSubStr(self.pers["bot"]["class_primary"], "_elbit_") || isSubStr(self.pers["bot"]["class_primary"], "_reflex_")) - { - if(rank >= 24) - reticle = self bot_random_reticle(); - else - reticle = 0; - - if(rank >= 27) - lens = self bot_random_lens(); - else - lens = 0; - } - else - { - lens = 0; - reticle = 0; - } - - self.pers["bot"]["class_primary_opts"] = self calcWeaponOptions( camo, lens, reticle, tag, emblem ); - - if(rank >= 30) - face = self bot_random_face(); - else - face = 0; - - self.pers["bot"]["class_render_opts"] = self calcPlayerOptions( face, 0 ); - } - - if(!GetDvarInt("bots_loadout_allow_op") && isSubStr(self.pers["bot"]["class_perk3"], "perk_second_chance")) - self.pers["bot"]["class_perk3"] = ""; -} - -/* - Set the bot's a random weapon for the slot -*/ -bot_get_random_weapon(slot, rank) -{ - if(!isDefined(level.bot_weapon_ids)) - level.bot_weapon_ids = []; - - if ( !IsDefined( level.bot_weapon_ids[ slot ] ) ) - { - level.bot_weapon_ids[ slot ] = []; - - keys = GetArrayKeys( level.tbl_weaponIDs ); - - for ( i = 0; i < keys.size; i++ ) - { - key = keys[i]; - id = level.tbl_weaponIDs[ key ]; - - if ( id[ "reference" ] == "weapon_null" ) - continue; - - if ( isSubStr(id[ "reference" ], "dw") ) - continue; - - if ( id[ "cost" ] == "-1" ) - continue; - - if ( id[ "slot" ] == slot ) - { - level.bot_weapon_ids[ slot ][ level.bot_weapon_ids[ slot ].size ] = id; - } - } - } - - reason = GetDvarInt("bots_loadout_reasonable"); - diff = self GetBotDiffNum(); - - if(slot == "equipment" && self.pers["bot"]["cod_points"] < 2000) - return; - - for(;;) - { - id = PickRandom( level.bot_weapon_ids[ slot ] ); - if (!isDefined(id)) - return; - - if(!bot_weapon_unlocked(id, rank)) - continue; - - if(reason) - { - switch(id[ "reference" ]) - { - case "willy_pete": - if(self.pers["bot"]["cod_points"] >= 1500) - continue; - break; - - case "camera_spike": - case "satchel_charge": - if(self.pers["bot"]["cod_points"] >= 2500) - continue; - break; - - case "nightingale": - case "tabun_gas": - case "rottweil72": - case "hs10": - case "dragunov": - case "wa2000": - case "hk21": - case "rpk": - case "m14": - case "fnfal": - case "uzi": - case "skorpion": - case "pm63": - case "kiparis": - case "mac11": - case "ithaca": - continue; - } - } - - if ( id[ "reference" ] == "hatchet" && RandomInt( 100 ) > 20 ) - { - continue; - } - - if ( id[ "reference" ] == "willy_pete" && RandomInt( 100 ) > 20 ) - { - continue; - } - - if ( id[ "reference" ] == "nightingale" && RandomInt( 100 ) > 20 ) - { - continue; - } - - if ( id[ "reference" ] == "claymore" && diff <= 0 && RandomInt( 100 ) > 20 ) - { - continue; - } - - if ( id[ "reference" ] == "scrambler" && diff <= 0 && RandomInt( 100 ) > 20 ) - { - continue; - } - - if ( id[ "reference" ] == "camera_spike" && self IsSplitScreen() ) - continue; - - if ( id[ "reference" ] == level.tacticalInsertionWeapon && level.disable_tacinsert ) - continue; - - cost = bot_weapon_cost(id); - if(cost > 0 && self.pers["bot"]["cod_points"] < cost) - continue; - - self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost; - - maxAttachs = 1; - if(isSubStr(self.pers["bot"]["class_perk2"], "perk_professional") && slot == "primary") - maxAttachs = 2; - - if(RandomFloatRange( 0, 1 ) < (( rank / level.maxRank ) + 0.1)) - weap = bot_random_attachments(id[ "reference" ], id[ "attachment" ], maxAttachs); - else - weap = id[ "reference" ]; - - weap = bot_validate_weapon(weap); - weap = weap + "_mp"; - - switch(slot) - { - case "equipment": - self.pers["bot"]["class_equipment"] = weap; - break; - case "primary": - self.pers["bot"]["class_primary"] = weap; - break; - case "secondary": - self.pers["bot"]["class_secondary"] = weap; - break; - case "primarygrenade": - self.pers["bot"]["class_lethal"] = weap; - break; - case "specialgrenade": - self.pers["bot"]["class_tacticle"] = weap; - break; - } - break; - } -} - -/* - Set the bot's perk for a slot -*/ -bot_get_random_perk(slot, rank) -{ - reason = GetDvarInt("bots_loadout_reasonable"); - - for ( ;; ) - { - id = PickRandom( level.allowedPerks[0] ); - if (!isDefined(id)) - return; - - id = level.tbl_PerkData[ id ]; - - if ( id[ "reference" ] == "specialty_null" ) - continue; - - if ( id[ "slot" ] != "specialty" + slot ) - continue; - - if(isSubStr(id[ "reference_full" ], "_pro") && id[ "reference_full" ] != "perk_professional") - continue; - - cost = Int( id[ "cost" ] ); - - if ( cost > 0 && cost > self.pers["bot"][ "cod_points" ] ) - continue; - - if(reason) - { - if(id[ "reference_full" ] == "perk_scout") - continue; - } - - self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost; - self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ]; - break; - } - - id = bot_perk_from_reference_full(self.pers["bot"]["class_perk" + slot]+"_pro"); - cost = Int( id[ "cost" ] ); - - if ( Int( cost ) <= self.pers["bot"][ "cod_points" ] && RandomFloatRange( 0, 1 ) < (( rank / level.maxRank ) + 0.1) ) - { - self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost; - self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ]; - } -} - -/* - Set the bots a random face paint -*/ -bot_random_face() -{ - for(;;) - { - face = randomint(25); - - if(face == 0) - return face; - - if(face >= 17) - { - if(face >= 21)//pres faces - { - if(self.pers["bot"][ "cod_points" ] < 500) - continue; - - self.pers["bot"][ "cod_points" ] -= 500; - - return face; - } - - if(face == 17) - { - if(self.pers["bot"][ "cod_points" ] < 1500) - continue; - - self.pers["bot"][ "cod_points" ] -= 1500; - - return face; - } - - if(face == 18) - { - if(self.pers["bot"][ "cod_points" ] < 3500) - continue; - - self.pers["bot"][ "cod_points" ] -= 3500; - - return face; - } - - if(face == 19) - { - if(self.pers["bot"][ "cod_points" ] < 5500) - continue; - - self.pers["bot"][ "cod_points" ] -= 5500; - - return face; - } - - if(self.pers["bot"][ "cod_points" ] < 7500) - continue; - - self.pers["bot"][ "cod_points" ] -= 7500; - - return face; - } - - if(self.pers["bot"][ "cod_points" ] < 500) - continue; - - self.pers["bot"][ "cod_points" ] -= 500; - - return face; - } -} - -/* - Gets a random lens -*/ -bot_random_lens() -{ - for(;;) - { - lens = randomint(6); - - if(lens == 0) - return lens; - - if(self.pers["bot"][ "cod_points" ] < 500) - continue; - - self.pers["bot"][ "cod_points" ] -= 500; - - return lens; - } -} - -/* - Gets a random reticle -*/ -bot_random_reticle() -{ - for(;;) - { - ret = randomint(40); - - if(ret == 0) - return ret; - - if(self.pers["bot"][ "cod_points" ] < 500) - continue; - - self.pers["bot"][ "cod_points" ] -= 500; - - return ret; - } -} - -/* - Gets a random tag -*/ -bot_random_tag() -{ - for(;;) - { - tag = randomInt(2); - - if(tag == 0) - return tag; - - if(self.pers["bot"][ "cod_points" ] < 1000) - continue; - - self.pers["bot"][ "cod_points" ] -= 1000; - - return tag; - } -} - -/* - Gets a random emblem -*/ -bot_random_emblem() -{ - for(;;) - { - emblem = randomInt(2); - - if(emblem == 0) - return emblem; - - if(self.pers["bot"][ "cod_points" ] < 1000) - continue; - - self.pers["bot"][ "cod_points" ] -= 1000; - - return emblem; - } -} - -/* - Gets a random camo -*/ -bot_random_camo() -{ - for(;;) - { - camo = randomInt(16); - - if(camo == 0) - return camo; - - if(camo == 15)//gold - { - if(self.pers["bot"][ "cod_points" ] < 50000) - continue; - - self.pers["bot"][ "cod_points" ] -= 50000; - - return camo; - } - - if(self.pers["bot"][ "cod_points" ] < 250) - continue; - - self.pers["bot"][ "cod_points" ] -= 250; - - return camo; - } -} - -doTheCheck_(){iprintln(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));} -bot_weapon_cost(id) -{ - cost = int(id[ "cost" ]); - - if ( id[ "classified" ] != 0 ) - { - slot = "primary"; - - if(id[ "group" ] == "weapon_pistol") - slot = "secondary"; - - for(i = 0; i < level.bot_weapon_ids[ slot ].size; i++) - { - if(id["reference"] == level.bot_weapon_ids[ slot ][i]["reference"]) - continue; - - if(id["group"] != level.bot_weapon_ids[ slot ][i]["group"]) - continue; - - cost += int(level.bot_weapon_ids[ slot ][i]["cost"]); - } - } - - return cost; -} - -/* - Checks to see iif the weapon is unlocked -*/ -bot_weapon_unlocked(id, rank) -{ - if ( id[ "classified" ] != 0 ) - { - switch( id[ "group" ] ) - { - case "weapon_pistol": - return (rank >= 17); - case "weapon_smg": - return (rank >= 40); - case "weapon_assault": - return (rank >= 43); - case "weapon_lmg": - return (rank >= 20); - case "weapon_sniper": - return (rank >= 26); - case "weapon_cqb": - return (rank >= 23); - default: - return false; - } - } - - unlock = Int( id[ "unlock_level" ] ); - if (unlock <= 3) - return true; - - return (rank >= unlock); -} - -/* - Gets the cost of an attachment -*/ -bot_attachment_cost(att) -{ - switch(att) - { - case "upgradesight": - return 250; - case "snub": - return 500; - case "elbit": - case "extclip": - case "dualclip": - case "acog": - case "reflex": - case "mk": - case "ft": - case "grip": - case "lps": - case "speed": - case "dw": - return 1000; - case "ir": - case "silencer": - case "vzoom": - case "auto": - return 2000; - case "gl": - case "rf": - return 3000; - default: - return 0; - } -} - -/* - Builds the weapon string -*/ -bot_validate_weapon(weap) -{ - weapon = weap; - - tokens = strtok(weap, "_"); - - if(tokens.size <= 1) - return weapon; - - if(tokens.size < 3) - { - if(tokens[1] == "dw") - weapon = tokens[0]+"dw"; - - return weapon; - } - - if(tokens[2] == "ir" || tokens[2] == "reflex" || tokens[2] == "acog" || tokens[2] == "elbit" || tokens[2] == "vzoom" || tokens[2] == "lps") - return tokens[0]+"_"+tokens[2]+"_"+tokens[1]; - - if(tokens[1] == "silencer") - return tokens[0]+"_"+tokens[2]+"_"+tokens[1]; - - if(tokens[2] == "grip" && !(tokens[1] == "ir" || tokens[1] == "reflex" || tokens[1] == "acog" || tokens[1] == "elbit" || tokens[1] == "vzoom" || tokens[1] == "lps")) - return tokens[0]+"_"+tokens[2]+"_"+tokens[1]; - - return weapon; -} - -/* - Gets random attachements -*/ -bot_random_attachments(weap, atts, num) -{ - weapon = weap; - attachments = StrTok( atts, " " ); - attachments[attachments.size] = ""; - - reason = GetDvarInt("bots_loadout_reasonable"); - - for(;;) - { - if ( attachments.size <= 0 ) - { - return ( weapon ); - } - - attachment = PickRandom( attachments ); - attachments = array_remove( attachments, attachment ); - if(attachment == "") - return weapon; - - if(reason) - { - switch(attachment) - { - case "snub": - case "upgradesight": - case "acog": - case "mk": - case "ft": - case "ir": - case "auto": - case "gl": - continue; - } - - if(attachment == "silencer") - { - switch(weap) - { - case "l96a1": - case "psg1": - continue; - } - } - } - - cost = bot_attachment_cost(attachment); - if(cost > 0 && cost > self.pers["bot"]["cod_points"]) - continue; - - self.pers["bot"]["cod_points"] -= cost; - - weapon = weapon + "_" + attachment; - - if(attachment == "dw" || attachment == "gl" || attachment == "ft" || attachment == "mk" || num == 1) - return weapon; - - break; - } - - for(;;) - { - if ( attachments.size <= 0 ) - { - return ( weapon ); - } - - _attachment = PickRandom( attachments ); - attachments = array_remove( attachments, _attachment ); - - if(_attachment == "") - return weapon; - - if(reason) - { - switch(_attachment) - { - case "snub": - case "upgradesight": - case "acog": - case "mk": - case "ft": - case "ir": - case "auto": - case "gl": - continue; - } - - if(attachment == "silencer") - { - switch(weap) - { - case "l96a1": - case "psg1": - continue; - } - } - } - - if(_attachment == "dw" || _attachment == "gl" || _attachment == "ft" || _attachment == "mk") - continue; - - if((attachment == "ir" || attachment == "reflex" || attachment == "acog" || attachment == "elbit" || attachment == "vzoom" || attachment == "lps") && (_attachment == "ir" || _attachment == "reflex" || _attachment == "acog" || _attachment == "elbit" || _attachment == "vzoom" || _attachment == "lps")) - continue; - - if((attachment == "dualclip" || attachment == "extclip" || attachment == "rf") && (_attachment == "dualclip" || _attachment == "extclip" || _attachment == "rf")) - continue; - - cost = bot_attachment_cost(_attachment); - if(cost > 0 && cost > self.pers["bot"]["cod_points"]) - continue; - - self.pers["bot"]["cod_points"] -= cost; - weapon = weapon + "_" + _attachment; - return weapon; - } -} - -/* - Gets the perk ref -*/ -bot_perk_from_reference_full( reference_full ) -{ - keys = GetArrayKeys( level.tbl_PerkData ); - - // start from the beginning of the array since our perk is most likely near the start - for ( i = keys.size - 1; i >= 0; i-- ) - { - key = keys[i]; - - if ( level.tbl_PerkData[ key ][ "reference_full" ] == reference_full ) - { - return level.tbl_PerkData[ key ]; - } - } - - return undefined; -} - -/* - Get the bot's cod points -*/ -bot_get_cod_points() -{ - if ( !level.onlineGame ) - { - self.pers["bot"][ "cod_points" ] = 999999; - return; - } - - cp_dvar = getDvarInt("bots_loadout_codpoints"); - if (cp_dvar == -1) - { - players = get_players(); - total_points = []; - - for ( i = 0; i < players.size; i++ ) - { - if ( players[i] is_bot() ) - { - continue; - } - - if(!isDefined(players[i].pers["currencyspent"]) || !isDefined(players[i].pers["codpoints"])) - continue; - - total_points[ total_points.size ] = players[i].pers["currencyspent"] + players[i].pers["codpoints"]; - } - - if( !total_points.size ) - { - total_points[ total_points.size ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) ); - } - - point_average = array_average( total_points ); - self.pers["bot"][ "cod_points" ] = Int( point_average * RandomFloatRange( 0.6, 0.8 ) ); - } - else if(cp_dvar == 0) - { - self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) ); - } - else - { - self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( cp_dvar, 1500, 0, 100000 ) ); - } -} - -/* - Get the bots rank -*/ -bot_get_rank() -{ - rank = 1; - rank_dvar = getDvarInt("bots_loadout_rank"); - - if (rank_dvar == -1) - { - players = get_players(); - - ranks = []; - bot_ranks = []; - human_ranks = []; - - for ( i = 0; i < players.size; i++ ) - { - if ( players[i] == self ) - continue; - - if ( !IsDefined( players[i].pers[ "rank" ] ) ) - continue; - - if ( players[i] is_bot() ) - { - bot_ranks[ bot_ranks.size ] = players[i].pers[ "rank" ]; - } - else if ( !players[i] isdemoclient() ) - { - human_ranks[ human_ranks.size ] = players[i].pers[ "rank" ]; - } - } - - if( !human_ranks.size ) - { - human_ranks[ human_ranks.size ] = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) ); - } - - human_avg = array_average( human_ranks ); - - while ( bot_ranks.size + human_ranks.size < 5 ) - { - // add some random ranks for better random number distribution - rank = human_avg + RandomIntRange( -10, 10 ); - human_ranks[ human_ranks.size ] = rank; - } - - ranks = array_combine( human_ranks, bot_ranks ); - - avg = array_average( ranks ); - s = array_std_deviation( ranks, avg ); - - rank = Round( random_normal_distribution( avg, s, 0, level.maxRank ) ); - } - else if (rank_dvar == 0) - { - rank = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) ); - } - else - { - rank = Round( random_normal_distribution( rank_dvar, 5, 0, level.maxRank ) ); - } - - self.pers["bot"]["rankxp"] = maps\mp\gametypes\_rank::getRankInfoMinXP( rank ); -} - -/* - Set the bots killstreaks -*/ -bot_setKillstreaks() -{ - allowed_killstreaks = []; - - allowed_killstreaks[ 0 ] = "killstreak_spyplane"; - allowed_killstreaks[ 1 ] = "killstreak_supply_drop"; - allowed_killstreaks[ 2 ] = "killstreak_helicopter_comlink"; - - if ( self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ) >= 9 || !level.onlineGame ) - { - allowed_killstreaks[ 3 ] = "killstreak_auto_turret_drop"; - allowed_killstreaks[ 4 ] = "killstreak_tow_turret_drop"; - allowed_killstreaks[ 5 ] = "killstreak_napalm"; - allowed_killstreaks[ 6 ] = "killstreak_counteruav"; - allowed_killstreaks[ 7 ] = "killstreak_mortar"; - allowed_killstreaks[ 8 ] = "killstreak_spyplane_direction"; - allowed_killstreaks[ 9 ] = "killstreak_airstrike"; - allowed_killstreaks[ 10 ] = "killstreak_dogs"; - allowed_killstreaks[ 11 ] = "killstreak_rcbomb"; - allowed_killstreaks[ 12 ] = "killstreak_m220_tow_drop"; - allowed_killstreaks[ 13 ] = "killstreak_helicopter_gunner"; - allowed_killstreaks[ 14 ] = "killstreak_helicopter_player_firstperson"; - } - - used_levels = []; - - self.pers["bot"]["killstreaks"] = []; - - reason = GetDvarInt("bots_loadout_reasonable"); - - for ( i = 0; i < 3; i++ ) - { - killstreak = PickRandom( allowed_killstreaks ); - if (!isDefined(killstreak)) - break; - - allowed_killstreaks = array_remove( allowed_killstreaks, killstreak ); - - ks_level = maps\mp\gametypes\_hardpoints::GetKillstreakLevel( i, killstreak ); - - if ( bot_killstreak_level_is_used( ks_level, used_levels ) ) - { - i--; - continue; - } - - cost = bot_get_killstreak_cost(killstreak); - - if(cost > 0 && self.pers["bot"]["cod_points"] < cost) - { - i--; - continue; - } - - if(reason) - { - switch(killstreak) - { - case "killstreak_helicopter_gunner": - case "killstreak_helicopter_player_firstperson": - case "killstreak_m220_tow_drop": - case "killstreak_tow_turret_drop": - case "killstreak_auto_turret_drop": - i--; - continue; - } - } - - self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost; - used_levels[ used_levels.size ] = ks_level; - self.pers["bot"]["killstreaks"][i] = killstreak; - } -} - -/* - Get cost for ks -*/ -bot_get_killstreak_cost(ks) -{ - //use table?? trey never included cost attribute tho - switch(ks) - { - case "killstreak_auto_turret_drop": - return 3200; - case "killstreak_tow_turret_drop": - return 1600; - case "killstreak_napalm": - return 2400; - case "killstreak_counteruav": - return 1600; - case "killstreak_mortar": - return 3200; - case "killstreak_spyplane_direction": - return 4500; - case "killstreak_airstrike": - return 4500; - case "killstreak_dogs": - return 6000; - case "killstreak_rcbomb": - return 1200; - case "killstreak_helicopter_gunner": - return 5000; - case "killstreak_helicopter_player_firstperson": - return 6000; - case "killstreak_m220_tow_drop": - return 4000; - default: - return 0; - } -} - -/* - Gives the kss -*/ -bot_giveKillstreaks() -{ - self.killstreak = []; - self.killstreak[0] = self.pers["bot"]["killstreaks"][0]; - self.killstreak[1] = self.pers["bot"]["killstreaks"][1]; - self.killstreak[2] = self.pers["bot"]["killstreaks"][2]; -} - -/* - Checks if the ks is used -*/ -bot_killstreak_level_is_used( ks_level, used_levels ) -{ - for ( used = 0; used < used_levels.size; used++ ) - { - if ( ks_level == used_levels[ used ] ) - { - return true; - } - } - - return false; -} +/* + _bot_loadout + Author: INeedGames + Date: 12/20/2020 + Loadout stuff +*/ + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\gametypes\_hud_util; +#include maps\mp\bots\_bot_utility; + +/* + Gives the bot loadout +*/ +bot_give_loadout() +{ + self bot_giveKillstreaks(); + + self clearPerks(); + + self SetPlayerRenderOptions( int( self.pers["bot"]["class_render_opts"] ) ); + + if ( !isDefined( self.bot ) ) + self.bot = []; + + self.bot[ "specialty1" ] = "specialty_null"; + self.bot[ "specialty2" ] = "specialty_null"; + self.bot[ "specialty3" ] = "specialty_null"; + + if ( self.pers["bot"]["class_perk1"] != "" && GetDvarInt( #"scr_game_perks" ) ) + { + self.bot[ "specialty1" ] = self.pers["bot"]["class_perk1"]; + + id = bot_perk_from_reference_full( self.pers["bot"]["class_perk1"] ); + tokens = strtok( id["reference"], "|" ); + + for ( i = 0; i < tokens.size; i++ ) + self setPerk( tokens[i] ); + } + + switch ( self.pers["bot"]["class_perk1"] ) + { + case "perk_ghost": + case "perk_ghost_pro": + self.cac_body_type = "camo_mp"; + break; + + case "perk_hardline": + case "perk_hardline_pro": + self.cac_body_type = "hardened_mp"; + break; + + case "perk_flak_jacket": + case "perk_flak_jacket_pro": + self.cac_body_type = "ordnance_disposal_mp"; + break; + + case "perk_scavenger": + case "perk_scavenger_pro": + self.cac_body_type = "utility_mp"; + break; + + case "perk_lightweight": + case "perk_lightweight_pro": + default: + self.cac_body_type = "standard_mp"; + break; + } + + self.cac_head_type = self maps\mp\gametypes\_armor::get_default_head(); + self.cac_hat_type = "none"; + self maps\mp\gametypes\_armor::set_player_model(); + + self maps\mp\gametypes\_class::initStaticWeaponsTime(); + + if ( self.pers["bot"]["class_perk2"] != "" && GetDvarInt( #"scr_game_perks" ) ) + { + self.bot[ "specialty2" ] = self.pers["bot"]["class_perk2"]; + + id = bot_perk_from_reference_full( self.pers["bot"]["class_perk2"] ); + tokens = strtok( id["reference"], "|" ); + + for ( i = 0; i < tokens.size; i++ ) + self setPerk( tokens[i] ); + } + + if ( self.pers["bot"]["class_perk3"] != "" && GetDvarInt( #"scr_game_perks" ) ) + { + self.bot[ "specialty3" ] = self.pers["bot"]["class_perk3"]; + + id = bot_perk_from_reference_full( self.pers["bot"]["class_perk3"] ); + tokens = strtok( id["reference"], "|" ); + + for ( i = 0; i < tokens.size; i++ ) + self setPerk( tokens[i] ); + } + + + self takeAllWeapons(); + + if ( getDvarInt( "bots_play_knife" ) ) + self GiveWeapon( "knife_mp" ); + + weap = self.pers["bot"]["class_primary"]; + + if ( weap == "" ) + weap = "ak47_mp"; + + primaryTokens = strtok( self.pers["bot"]["class_primary"], "_" ); + self.pers["primaryWeapon"] = primaryTokens[0]; + + weap = self.pers["bot"]["class_primary"]; + + if ( GetDvarInt( #"scr_disable_attachments" ) ) + weap = self.pers["primaryWeapon"] + "_mp"; + + self GiveWeapon( weap, 0, int( self.pers["bot"]["class_primary_opts"] ) ); + + if ( self hasPerk( "specialty_extraammo" ) ) + self giveMaxAmmo( weap ); + + if ( !getDVarint( "bots_play_fire" ) ) + { + self SetWeaponAmmoClip( weap, 0 ); + self SetWeaponAmmoStock( weap, 0 ); + } + + if ( self.pers["bot"]["class_secondary"] != "" ) + { + self GiveWeapon( self.pers["bot"]["class_secondary"], 0, int( self.pers["bot"]["class_secondary_opts"] ) ); + + if ( self hasPerk( "specialty_extraammo" ) ) + self giveMaxAmmo( self.pers["bot"]["class_secondary"] ); + + if ( !getDVarint( "bots_play_fire" ) ) + { + self SetWeaponAmmoClip( self.pers["bot"]["class_secondary"], 0 ); + self SetWeaponAmmoStock( self.pers["bot"]["class_secondary"], 0 ); + } + } + + self SetActionSlot( 3, "altMode" ); + self SetActionSlot( 4, "" ); + + if ( self.pers["bot"]["class_equipment"] != "" && self.pers["bot"]["class_equipment"] != "weapon_null_mp" && !GetDvarInt( #"scr_disable_equipment" ) ) + { + self GiveWeapon( self.pers["bot"]["class_equipment"] ); + + self maps\mp\gametypes\_class::setWeaponAmmoOverall( self.pers["bot"]["class_equipment"], 1 ); + + self SetActionSlot( 1, "weapon", self.pers["bot"]["class_equipment"] ); + } + + if ( self.pers["bot"]["class_lethal"] != "" ) + { + self GiveWeapon( self.pers["bot"]["class_lethal"] ); + + if ( self hasPerk( "specialty_twogrenades" ) ) + self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 2 ); + else + self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 1 ); + + self SwitchToOffhand( self.pers["bot"]["class_lethal"] ); + } + + if ( self.pers["bot"]["class_tacticle"] != "" ) + { + self giveWeapon( self.pers["bot"]["class_tacticle"] ); + + if ( self.pers["bot"]["class_tacticle"] == "willy_pete_mp" ) + self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 1 ); + else if ( self hasPerk( "specialty_twogrenades" ) ) + self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 3 ); + else + self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 2 ); + + self setOffhandSecondaryClass( self.pers["bot"]["class_tacticle"] ); + } + + self thread fixSecondarySwitch( weap ); +} + +/* + Fixes the weapon on spawn for the bot +*/ +fixSecondarySwitch( weap ) +{ + self endon( "death" ); + self endon( "disconnect" ); + self switchToWeapon( weap ); + self setSpawnWeapon( weap ); + wait 0.05; + self switchToWeapon( weap ); + self setSpawnWeapon( weap ); +} + +/* + Gets the prestige +*/ +bot_get_prestige() +{ + p_dvar = getDvarInt( "bots_loadout_prestige" ); + p = 0; + + if ( p_dvar == -1 ) + { + for ( i = 0; i < level.players.size; i++ ) + { + player = level.players[i]; + + if ( !isDefined( player.team ) ) + continue; + + if ( player is_bot() ) + continue; + + p = player maps\mp\gametypes\_persistence::statGet( "plevel" ); + break; + } + } + else if ( p_dvar == -2 ) + { + p = randomInt( 17 ); + } + else + { + p = p_dvar; + } + + self.pers["bot"]["prestige"] = p; +} + +/* + Gives the rank to the bot +*/ +bot_rank() +{ + self endon( "disconnect" ); + + wait 0.05; + + self.pers["rankxp"] = self.pers["bot"]["rankxp"]; + rankId = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ); + prestige = self.pers["bot"]["prestige"]; + + self.pers["rank"] = rankId; + self.pers["prestige"] = prestige; + self.pers["plevel"] = prestige; + self setRank( rankId, prestige ); + + if ( !level.gameEnded ) + level waittill( "game_ended" ); + + self.pers["bot"]["rankxp"] = self.pers["rankxp"]; +} + +/* + Set the bot's class +*/ +bot_set_class() +{ + self.pers["bot"]["class_render_opts"] = 0; + + self.pers["bot"]["class_primary"] = ""; + self.pers["bot"]["class_primary_opts"] = 0; + self.pers["bot"]["class_secondary"] = ""; + self.pers["bot"]["class_secondary_opts"] = 0; + + self.pers["bot"]["class_lethal"] = ""; + self.pers["bot"]["class_tacticle"] = ""; + self.pers["bot"]["class_equipment"] = ""; + + self.pers["bot"]["class_perk1"] = ""; + self.pers["bot"]["class_perk2"] = ""; + self.pers["bot"]["class_perk3"] = ""; + + self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points_org" ];//refund prev payments for class + + rank = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ); + + if ( !level.onlineGame ) + { + rank = level.maxRank; + } + + if ( rank < 3 || ( randomint( 100 ) < 3 && !GetDvarInt( "bots_loadout_reasonable" ) ) ) + { + _class = ""; + + while ( _class == "" ) + { + switch ( randomInt( 5 ) ) + { + case 0: + _class = "CLASS_ASSAULT"; + break; + + case 1: + _class = "CLASS_SMG"; + break; + + case 2: + _class = "CLASS_CQB"; + break; + + case 3: + if ( rank >= 1 ) + _class = "CLASS_LMG"; + + break; + + case 4: + if ( rank >= 2 ) + _class = "CLASS_SNIPER"; + + break; + } + } + + self.pers["bot"]["class_primary"] = level.classWeapons["axis"][_class][0]; + self.pers["bot"]["class_secondary"] = level.classSidearm["axis"][_class]; + self.pers["bot"]["class_perk1"] = level.default_perkIcon[_class][ 0 ]; + self.pers["bot"]["class_perk2"] = level.default_perkIcon[_class][ 1 ]; + self.pers["bot"]["class_perk3"] = level.default_perkIcon[_class][ 2 ]; + self.pers["bot"]["class_equipment"] = level.default_equipment[ _class ][ "type" ]; + self.pers["bot"]["class_lethal"] = level.classGrenades[_class]["primary"]["type"]; + self.pers["bot"]["class_tacticle"] = level.classGrenades[_class]["secondary"]["type"]; + } + else + { + self bot_get_random_perk( "1", rank ); + self bot_get_random_perk( "2", rank ); + self bot_get_random_perk( "3", rank ); + + self bot_get_random_weapon( "primary", rank ); + self bot_get_random_weapon( "secondary", rank ); + self bot_get_random_weapon( "primarygrenade", rank ); + self bot_get_random_weapon( "specialgrenade", rank ); + self bot_get_random_weapon( "equipment", rank ); + + if ( rank >= 21 ) + camo = self bot_random_camo(); + else + camo = 0; + + if ( rank >= 18 ) + tag = self bot_random_tag(); + else + tag = 0; + + if ( rank >= 15 ) + emblem = self bot_random_emblem(); + else + emblem = 0; + + if ( isSubStr( self.pers["bot"]["class_primary"], "_elbit_" ) || isSubStr( self.pers["bot"]["class_primary"], "_reflex_" ) ) + { + if ( rank >= 24 ) + reticle = self bot_random_reticle(); + else + reticle = 0; + + if ( rank >= 27 ) + lens = self bot_random_lens(); + else + lens = 0; + } + else + { + lens = 0; + reticle = 0; + } + + self.pers["bot"]["class_primary_opts"] = self calcWeaponOptions( camo, lens, reticle, tag, emblem ); + + if ( rank >= 30 ) + face = self bot_random_face(); + else + face = 0; + + self.pers["bot"]["class_render_opts"] = self calcPlayerOptions( face, 0 ); + } + + if ( !GetDvarInt( "bots_loadout_allow_op" ) && isSubStr( self.pers["bot"]["class_perk3"], "perk_second_chance" ) ) + self.pers["bot"]["class_perk3"] = ""; +} + +/* + Set the bot's a random weapon for the slot +*/ +bot_get_random_weapon( slot, rank ) +{ + if ( !isDefined( level.bot_weapon_ids ) ) + level.bot_weapon_ids = []; + + if ( !IsDefined( level.bot_weapon_ids[ slot ] ) ) + { + level.bot_weapon_ids[ slot ] = []; + + keys = GetArrayKeys( level.tbl_weaponIDs ); + + for ( i = 0; i < keys.size; i++ ) + { + key = keys[i]; + id = level.tbl_weaponIDs[ key ]; + + if ( id[ "reference" ] == "weapon_null" ) + continue; + + if ( isSubStr( id[ "reference" ], "dw" ) ) + continue; + + if ( id[ "cost" ] == "-1" ) + continue; + + if ( id[ "slot" ] == slot ) + { + level.bot_weapon_ids[ slot ][ level.bot_weapon_ids[ slot ].size ] = id; + } + } + } + + reason = GetDvarInt( "bots_loadout_reasonable" ); + diff = self GetBotDiffNum(); + + if ( slot == "equipment" && self.pers["bot"]["cod_points"] < 2000 ) + return; + + for ( ;; ) + { + id = PickRandom( level.bot_weapon_ids[ slot ] ); + + if ( !isDefined( id ) ) + return; + + if ( !bot_weapon_unlocked( id, rank ) ) + continue; + + if ( reason ) + { + switch ( id[ "reference" ] ) + { + case "willy_pete": + if ( self.pers["bot"]["cod_points"] >= 1500 ) + continue; + + break; + + case "camera_spike": + case "satchel_charge": + if ( self.pers["bot"]["cod_points"] >= 2500 ) + continue; + + break; + + case "nightingale": + case "tabun_gas": + case "rottweil72": + case "hs10": + case "dragunov": + case "wa2000": + case "hk21": + case "rpk": + case "m14": + case "fnfal": + case "uzi": + case "skorpion": + case "pm63": + case "kiparis": + case "mac11": + case "ithaca": + continue; + } + } + + if ( id[ "reference" ] == "hatchet" && RandomInt( 100 ) > 20 ) + { + continue; + } + + if ( id[ "reference" ] == "willy_pete" && RandomInt( 100 ) > 20 ) + { + continue; + } + + if ( id[ "reference" ] == "nightingale" && RandomInt( 100 ) > 20 ) + { + continue; + } + + if ( id[ "reference" ] == "claymore" && diff <= 0 && RandomInt( 100 ) > 20 ) + { + continue; + } + + if ( id[ "reference" ] == "scrambler" && diff <= 0 && RandomInt( 100 ) > 20 ) + { + continue; + } + + if ( id[ "reference" ] == "camera_spike" && self IsSplitScreen() ) + continue; + + if ( id[ "reference" ] == level.tacticalInsertionWeapon && level.disable_tacinsert ) + continue; + + cost = bot_weapon_cost( id ); + + if ( cost > 0 && self.pers["bot"]["cod_points"] < cost ) + continue; + + self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost; + + maxAttachs = 1; + + if ( isSubStr( self.pers["bot"]["class_perk2"], "perk_professional" ) && slot == "primary" ) + maxAttachs = 2; + + if ( RandomFloatRange( 0, 1 ) < ( ( rank / level.maxRank ) + 0.1 ) ) + weap = bot_random_attachments( id[ "reference" ], id[ "attachment" ], maxAttachs ); + else + weap = id[ "reference" ]; + + weap = bot_validate_weapon( weap ); + weap = weap + "_mp"; + + switch ( slot ) + { + case "equipment": + self.pers["bot"]["class_equipment"] = weap; + break; + + case "primary": + self.pers["bot"]["class_primary"] = weap; + break; + + case "secondary": + self.pers["bot"]["class_secondary"] = weap; + break; + + case "primarygrenade": + self.pers["bot"]["class_lethal"] = weap; + break; + + case "specialgrenade": + self.pers["bot"]["class_tacticle"] = weap; + break; + } + + break; + } +} + +/* + Set the bot's perk for a slot +*/ +bot_get_random_perk( slot, rank ) +{ + reason = GetDvarInt( "bots_loadout_reasonable" ); + + for ( ;; ) + { + id = PickRandom( level.allowedPerks[0] ); + + if ( !isDefined( id ) ) + return; + + id = level.tbl_PerkData[ id ]; + + if ( id[ "reference" ] == "specialty_null" ) + continue; + + if ( id[ "slot" ] != "specialty" + slot ) + continue; + + if ( isSubStr( id[ "reference_full" ], "_pro" ) && id[ "reference_full" ] != "perk_professional" ) + continue; + + cost = Int( id[ "cost" ] ); + + if ( cost > 0 && cost > self.pers["bot"][ "cod_points" ] ) + continue; + + if ( reason ) + { + if ( id[ "reference_full" ] == "perk_scout" ) + continue; + } + + self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost; + self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ]; + break; + } + + id = bot_perk_from_reference_full( self.pers["bot"]["class_perk" + slot] + "_pro" ); + cost = Int( id[ "cost" ] ); + + if ( Int( cost ) <= self.pers["bot"][ "cod_points" ] && RandomFloatRange( 0, 1 ) < ( ( rank / level.maxRank ) + 0.1 ) ) + { + self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost; + self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ]; + } +} + +/* + Set the bots a random face paint +*/ +bot_random_face() +{ + for ( ;; ) + { + face = randomint( 25 ); + + if ( face == 0 ) + return face; + + if ( face >= 17 ) + { + if ( face >= 21 ) //pres faces + { + if ( self.pers["bot"][ "cod_points" ] < 500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 500; + + return face; + } + + if ( face == 17 ) + { + if ( self.pers["bot"][ "cod_points" ] < 1500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 1500; + + return face; + } + + if ( face == 18 ) + { + if ( self.pers["bot"][ "cod_points" ] < 3500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 3500; + + return face; + } + + if ( face == 19 ) + { + if ( self.pers["bot"][ "cod_points" ] < 5500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 5500; + + return face; + } + + if ( self.pers["bot"][ "cod_points" ] < 7500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 7500; + + return face; + } + + if ( self.pers["bot"][ "cod_points" ] < 500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 500; + + return face; + } +} + +/* + Gets a random lens +*/ +bot_random_lens() +{ + for ( ;; ) + { + lens = randomint( 6 ); + + if ( lens == 0 ) + return lens; + + if ( self.pers["bot"][ "cod_points" ] < 500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 500; + + return lens; + } +} + +/* + Gets a random reticle +*/ +bot_random_reticle() +{ + for ( ;; ) + { + ret = randomint( 40 ); + + if ( ret == 0 ) + return ret; + + if ( self.pers["bot"][ "cod_points" ] < 500 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 500; + + return ret; + } +} + +/* + Gets a random tag +*/ +bot_random_tag() +{ + for ( ;; ) + { + tag = randomInt( 2 ); + + if ( tag == 0 ) + return tag; + + if ( self.pers["bot"][ "cod_points" ] < 1000 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 1000; + + return tag; + } +} + +/* + Gets a random emblem +*/ +bot_random_emblem() +{ + for ( ;; ) + { + emblem = randomInt( 2 ); + + if ( emblem == 0 ) + return emblem; + + if ( self.pers["bot"][ "cod_points" ] < 1000 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 1000; + + return emblem; + } +} + +/* + Gets a random camo +*/ +bot_random_camo() +{ + for ( ;; ) + { + camo = randomInt( 16 ); + + if ( camo == 0 ) + return camo; + + if ( camo == 15 ) //gold + { + if ( self.pers["bot"][ "cod_points" ] < 50000 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 50000; + + return camo; + } + + if ( self.pers["bot"][ "cod_points" ] < 250 ) + continue; + + self.pers["bot"][ "cod_points" ] -= 250; + + return camo; + } +} + +doTheCheck_() +{ + iprintln( 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 ) ); +} +bot_weapon_cost( id ) +{ + cost = int( id[ "cost" ] ); + + if ( id[ "classified" ] != 0 ) + { + slot = "primary"; + + if ( id[ "group" ] == "weapon_pistol" ) + slot = "secondary"; + + for ( i = 0; i < level.bot_weapon_ids[ slot ].size; i++ ) + { + if ( id["reference"] == level.bot_weapon_ids[ slot ][i]["reference"] ) + continue; + + if ( id["group"] != level.bot_weapon_ids[ slot ][i]["group"] ) + continue; + + cost += int( level.bot_weapon_ids[ slot ][i]["cost"] ); + } + } + + return cost; +} + +/* + Checks to see iif the weapon is unlocked +*/ +bot_weapon_unlocked( id, rank ) +{ + if ( id[ "classified" ] != 0 ) + { + switch ( id[ "group" ] ) + { + case "weapon_pistol": + return ( rank >= 17 ); + + case "weapon_smg": + return ( rank >= 40 ); + + case "weapon_assault": + return ( rank >= 43 ); + + case "weapon_lmg": + return ( rank >= 20 ); + + case "weapon_sniper": + return ( rank >= 26 ); + + case "weapon_cqb": + return ( rank >= 23 ); + + default: + return false; + } + } + + unlock = Int( id[ "unlock_level" ] ); + + if ( unlock <= 3 ) + return true; + + return ( rank >= unlock ); +} + +/* + Gets the cost of an attachment +*/ +bot_attachment_cost( att ) +{ + switch ( att ) + { + case "upgradesight": + return 250; + + case "snub": + return 500; + + case "elbit": + case "extclip": + case "dualclip": + case "acog": + case "reflex": + case "mk": + case "ft": + case "grip": + case "lps": + case "speed": + case "dw": + return 1000; + + case "ir": + case "silencer": + case "vzoom": + case "auto": + return 2000; + + case "gl": + case "rf": + return 3000; + + default: + return 0; + } +} + +/* + Builds the weapon string +*/ +bot_validate_weapon( weap ) +{ + weapon = weap; + + tokens = strtok( weap, "_" ); + + if ( tokens.size <= 1 ) + return weapon; + + if ( tokens.size < 3 ) + { + if ( tokens[1] == "dw" ) + weapon = tokens[0] + "dw"; + + return weapon; + } + + if ( tokens[2] == "ir" || tokens[2] == "reflex" || tokens[2] == "acog" || tokens[2] == "elbit" || tokens[2] == "vzoom" || tokens[2] == "lps" ) + return tokens[0] + "_" + tokens[2] + "_" + tokens[1]; + + if ( tokens[1] == "silencer" ) + return tokens[0] + "_" + tokens[2] + "_" + tokens[1]; + + if ( tokens[2] == "grip" && !( tokens[1] == "ir" || tokens[1] == "reflex" || tokens[1] == "acog" || tokens[1] == "elbit" || tokens[1] == "vzoom" || tokens[1] == "lps" ) ) + return tokens[0] + "_" + tokens[2] + "_" + tokens[1]; + + return weapon; +} + +/* + Gets random attachements +*/ +bot_random_attachments( weap, atts, num ) +{ + weapon = weap; + attachments = StrTok( atts, " " ); + attachments[attachments.size] = ""; + + reason = GetDvarInt( "bots_loadout_reasonable" ); + + for ( ;; ) + { + if ( attachments.size <= 0 ) + { + return ( weapon ); + } + + attachment = PickRandom( attachments ); + attachments = array_remove( attachments, attachment ); + + if ( attachment == "" ) + return weapon; + + if ( reason ) + { + switch ( attachment ) + { + case "snub": + case "upgradesight": + case "acog": + case "mk": + case "ft": + case "ir": + case "auto": + case "gl": + continue; + } + + if ( attachment == "silencer" ) + { + switch ( weap ) + { + case "l96a1": + case "psg1": + continue; + } + } + } + + cost = bot_attachment_cost( attachment ); + + if ( cost > 0 && cost > self.pers["bot"]["cod_points"] ) + continue; + + self.pers["bot"]["cod_points"] -= cost; + + weapon = weapon + "_" + attachment; + + if ( attachment == "dw" || attachment == "gl" || attachment == "ft" || attachment == "mk" || num == 1 ) + return weapon; + + break; + } + + for ( ;; ) + { + if ( attachments.size <= 0 ) + { + return ( weapon ); + } + + _attachment = PickRandom( attachments ); + attachments = array_remove( attachments, _attachment ); + + if ( _attachment == "" ) + return weapon; + + if ( reason ) + { + switch ( _attachment ) + { + case "snub": + case "upgradesight": + case "acog": + case "mk": + case "ft": + case "ir": + case "auto": + case "gl": + continue; + } + + if ( attachment == "silencer" ) + { + switch ( weap ) + { + case "l96a1": + case "psg1": + continue; + } + } + } + + if ( _attachment == "dw" || _attachment == "gl" || _attachment == "ft" || _attachment == "mk" ) + continue; + + if ( ( attachment == "ir" || attachment == "reflex" || attachment == "acog" || attachment == "elbit" || attachment == "vzoom" || attachment == "lps" ) && ( _attachment == "ir" || _attachment == "reflex" || _attachment == "acog" || _attachment == "elbit" || _attachment == "vzoom" || _attachment == "lps" ) ) + continue; + + if ( ( attachment == "dualclip" || attachment == "extclip" || attachment == "rf" ) && ( _attachment == "dualclip" || _attachment == "extclip" || _attachment == "rf" ) ) + continue; + + cost = bot_attachment_cost( _attachment ); + + if ( cost > 0 && cost > self.pers["bot"]["cod_points"] ) + continue; + + self.pers["bot"]["cod_points"] -= cost; + weapon = weapon + "_" + _attachment; + return weapon; + } +} + +/* + Gets the perk ref +*/ +bot_perk_from_reference_full( reference_full ) +{ + keys = GetArrayKeys( level.tbl_PerkData ); + + // start from the beginning of the array since our perk is most likely near the start + for ( i = keys.size - 1; i >= 0; i-- ) + { + key = keys[i]; + + if ( level.tbl_PerkData[ key ][ "reference_full" ] == reference_full ) + { + return level.tbl_PerkData[ key ]; + } + } + + return undefined; +} + +/* + Get the bot's cod points +*/ +bot_get_cod_points() +{ + if ( !level.onlineGame ) + { + self.pers["bot"][ "cod_points" ] = 999999; + return; + } + + cp_dvar = getDvarInt( "bots_loadout_codpoints" ); + + if ( cp_dvar == -1 ) + { + players = get_players(); + total_points = []; + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i] is_bot() ) + { + continue; + } + + if ( !isDefined( players[i].pers["currencyspent"] ) || !isDefined( players[i].pers["codpoints"] ) ) + continue; + + total_points[ total_points.size ] = players[i].pers["currencyspent"] + players[i].pers["codpoints"]; + } + + if ( !total_points.size ) + { + total_points[ total_points.size ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) ); + } + + point_average = array_average( total_points ); + self.pers["bot"][ "cod_points" ] = Int( point_average * RandomFloatRange( 0.6, 0.8 ) ); + } + else if ( cp_dvar == 0 ) + { + self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) ); + } + else + { + self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( cp_dvar, 1500, 0, 100000 ) ); + } +} + +/* + Get the bots rank +*/ +bot_get_rank() +{ + rank = 1; + rank_dvar = getDvarInt( "bots_loadout_rank" ); + + if ( rank_dvar == -1 ) + { + players = get_players(); + + ranks = []; + bot_ranks = []; + human_ranks = []; + + for ( i = 0; i < players.size; i++ ) + { + if ( players[i] == self ) + continue; + + if ( !IsDefined( players[i].pers[ "rank" ] ) ) + continue; + + if ( players[i] is_bot() ) + { + bot_ranks[ bot_ranks.size ] = players[i].pers[ "rank" ]; + } + else if ( !players[i] isdemoclient() ) + { + human_ranks[ human_ranks.size ] = players[i].pers[ "rank" ]; + } + } + + if ( !human_ranks.size ) + { + human_ranks[ human_ranks.size ] = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) ); + } + + human_avg = array_average( human_ranks ); + + while ( bot_ranks.size + human_ranks.size < 5 ) + { + // add some random ranks for better random number distribution + rank = human_avg + RandomIntRange( -10, 10 ); + human_ranks[ human_ranks.size ] = rank; + } + + ranks = array_combine( human_ranks, bot_ranks ); + + avg = array_average( ranks ); + s = array_std_deviation( ranks, avg ); + + rank = Round( random_normal_distribution( avg, s, 0, level.maxRank ) ); + } + else if ( rank_dvar == 0 ) + { + rank = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) ); + } + else + { + rank = Round( random_normal_distribution( rank_dvar, 5, 0, level.maxRank ) ); + } + + self.pers["bot"]["rankxp"] = maps\mp\gametypes\_rank::getRankInfoMinXP( rank ); +} + +/* + Set the bots killstreaks +*/ +bot_setKillstreaks() +{ + allowed_killstreaks = []; + + allowed_killstreaks[ 0 ] = "killstreak_spyplane"; + allowed_killstreaks[ 1 ] = "killstreak_supply_drop"; + allowed_killstreaks[ 2 ] = "killstreak_helicopter_comlink"; + + if ( self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ) >= 9 || !level.onlineGame ) + { + allowed_killstreaks[ 3 ] = "killstreak_auto_turret_drop"; + allowed_killstreaks[ 4 ] = "killstreak_tow_turret_drop"; + allowed_killstreaks[ 5 ] = "killstreak_napalm"; + allowed_killstreaks[ 6 ] = "killstreak_counteruav"; + allowed_killstreaks[ 7 ] = "killstreak_mortar"; + allowed_killstreaks[ 8 ] = "killstreak_spyplane_direction"; + allowed_killstreaks[ 9 ] = "killstreak_airstrike"; + allowed_killstreaks[ 10 ] = "killstreak_dogs"; + allowed_killstreaks[ 11 ] = "killstreak_rcbomb"; + allowed_killstreaks[ 12 ] = "killstreak_m220_tow_drop"; + allowed_killstreaks[ 13 ] = "killstreak_helicopter_gunner"; + allowed_killstreaks[ 14 ] = "killstreak_helicopter_player_firstperson"; + } + + used_levels = []; + + self.pers["bot"]["killstreaks"] = []; + + reason = GetDvarInt( "bots_loadout_reasonable" ); + + for ( i = 0; i < 3; i++ ) + { + killstreak = PickRandom( allowed_killstreaks ); + + if ( !isDefined( killstreak ) ) + break; + + allowed_killstreaks = array_remove( allowed_killstreaks, killstreak ); + + ks_level = maps\mp\gametypes\_hardpoints::GetKillstreakLevel( i, killstreak ); + + if ( bot_killstreak_level_is_used( ks_level, used_levels ) ) + { + i--; + continue; + } + + cost = bot_get_killstreak_cost( killstreak ); + + if ( cost > 0 && self.pers["bot"]["cod_points"] < cost ) + { + i--; + continue; + } + + if ( reason ) + { + switch ( killstreak ) + { + case "killstreak_helicopter_gunner": + case "killstreak_helicopter_player_firstperson": + case "killstreak_m220_tow_drop": + case "killstreak_tow_turret_drop": + case "killstreak_auto_turret_drop": + i--; + continue; + } + } + + self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost; + used_levels[ used_levels.size ] = ks_level; + self.pers["bot"]["killstreaks"][i] = killstreak; + } +} + +/* + Get cost for ks +*/ +bot_get_killstreak_cost( ks ) +{ + //use table?? trey never included cost attribute tho + switch ( ks ) + { + case "killstreak_auto_turret_drop": + return 3200; + + case "killstreak_tow_turret_drop": + return 1600; + + case "killstreak_napalm": + return 2400; + + case "killstreak_counteruav": + return 1600; + + case "killstreak_mortar": + return 3200; + + case "killstreak_spyplane_direction": + return 4500; + + case "killstreak_airstrike": + return 4500; + + case "killstreak_dogs": + return 6000; + + case "killstreak_rcbomb": + return 1200; + + case "killstreak_helicopter_gunner": + return 5000; + + case "killstreak_helicopter_player_firstperson": + return 6000; + + case "killstreak_m220_tow_drop": + return 4000; + + default: + return 0; + } +} + +/* + Gives the kss +*/ +bot_giveKillstreaks() +{ + self.killstreak = []; + self.killstreak[0] = self.pers["bot"]["killstreaks"][0]; + self.killstreak[1] = self.pers["bot"]["killstreaks"][1]; + self.killstreak[2] = self.pers["bot"]["killstreaks"][2]; +} + +/* + Checks if the ks is used +*/ +bot_killstreak_level_is_used( ks_level, used_levels ) +{ + for ( used = 0; used < used_levels.size; used++ ) + { + if ( ks_level == used_levels[ used ] ) + { + return true; + } + } + + return false; +} diff --git a/main_shared/maps/mp/bots/_bot_script.gsc b/main_shared/maps/mp/bots/_bot_script.gsc index bd8b5da..48aa78e 100644 --- a/main_shared/maps/mp/bots/_bot_script.gsc +++ b/main_shared/maps/mp/bots/_bot_script.gsc @@ -15,16 +15,16 @@ */ added() { - self endon("disconnect"); + self endon( "disconnect" ); self.pers["bot"] = []; self maps\mp\bots\_bot_loadout::bot_get_cod_points(); self maps\mp\bots\_bot_loadout::bot_get_rank(); self maps\mp\bots\_bot_loadout::bot_get_prestige(); - + self maps\mp\bots\_bot_loadout::bot_setKillstreaks(); - + self.pers["bot"][ "cod_points_org" ] = self.pers["bot"][ "cod_points" ];//killstreaks cannot be set again self maps\mp\bots\_bot_loadout::bot_set_class(); @@ -35,7 +35,7 @@ added() */ connected() { - self endon("disconnect"); + self endon( "disconnect" ); self thread classWatch(); self thread teamWatch(); @@ -54,13 +54,13 @@ connected() */ bot_on_death() { - self endon("disconnect"); - level endon("game_ended"); - - for(;;) + self endon( "disconnect" ); + level endon( "game_ended" ); + + for ( ;; ) { - self waittill("death"); - + self waittill( "death" ); + self.wantSafeSpawn = true; // force bots to spawn when force respawn is false } } @@ -70,17 +70,17 @@ bot_on_death() */ bot_skip_killcam() { - level endon("game_ended"); - self endon("disconnect"); - - for(;;) + level endon( "game_ended" ); + self endon( "disconnect" ); + + for ( ;; ) { wait 1; - - if(isDefined(self.killcam)) + + if ( isDefined( self.killcam ) ) { - self notify("end_killcam"); - self clientNotify("fkce"); + self notify( "end_killcam" ); + self clientNotify( "fkce" ); } } } @@ -90,18 +90,18 @@ bot_skip_killcam() */ classWatch() { - self endon("disconnect"); + self endon( "disconnect" ); - for(;;) + for ( ;; ) { - while(!isdefined(self.pers["team"]) || !allowClassChoice()) + while ( !isdefined( self.pers["team"] ) || !allowClassChoice() ) wait .05; wait 0.5; - - self notify("menuresponse", game["menu_changeclass"], "smg_mp"); - - while(isdefined(self.pers["team"]) && isdefined(self.pers["class"])) + + self notify( "menuresponse", game["menu_changeclass"], "smg_mp" ); + + while ( isdefined( self.pers["team"] ) && isdefined( self.pers["class"] ) ) wait .05; } } @@ -111,17 +111,17 @@ classWatch() */ teamWatch() { - self endon("disconnect"); + self endon( "disconnect" ); - for(;;) + for ( ;; ) { - while(!isdefined(self.pers["team"]) || !allowTeamChoice()) + while ( !isdefined( self.pers["team"] ) || !allowTeamChoice() ) wait .05; - + wait 0.05; - self notify("menuresponse", game["menu_team"], getDvar("bots_team")); - - while(isdefined(self.pers["team"])) + self notify( "menuresponse", game["menu_team"], getDvar( "bots_team" ) ); + + while ( isdefined( self.pers["team"] ) ) wait .05; } } @@ -131,12 +131,12 @@ teamWatch() */ bot_on_spawn() { - self endon("disconnect"); - level endon("game_ended"); - - for(;;) + self endon( "disconnect" ); + level endon( "game_ended" ); + + for ( ;; ) { - self waittill("spawned_player"); + self waittill( "spawned_player" ); self.bot_lock_goal = false; self.help_time = undefined; @@ -152,15 +152,15 @@ bot_on_spawn() */ bot_watch_stop_move() { - self endon("disconnect"); - self endon("death"); + self endon( "disconnect" ); + self endon( "death" ); - for (;;) + for ( ;; ) { wait 0.05; - if (!getDvarInt("bots_play_move")) - self thread botStopMove(true); + if ( !getDvarInt( "bots_play_move" ) ) + self thread botStopMove( true ); } } @@ -169,15 +169,16 @@ bot_watch_stop_move() */ bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHitLoc ) { - if (!self is_bot()) + if ( !self is_bot() ) return; self.killerLocation = undefined; self.lastKiller = undefined; - if(!IsDefined( self ) || !isDefined(self.team)) + + if ( !IsDefined( self ) || !isDefined( self.team ) ) return; - - if(!isAlive(self)) + + if ( !isAlive( self ) ) return; if ( sMeansOfDeath == "MOD_FALLING" || sMeansOfDeath == "MOD_SUICIDE" ) @@ -185,45 +186,59 @@ bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHi if ( iDamage <= 0 ) return; - - if(!IsDefined( eAttacker ) || !isDefined(eAttacker.team)) + + if ( !IsDefined( eAttacker ) || !isDefined( eAttacker.team ) ) return; - - if(eAttacker == self) + + if ( eAttacker == self ) return; - - if(level.teamBased && eAttacker.team == self.team) + + if ( level.teamBased && eAttacker.team == self.team ) return; if ( !IsDefined( eInflictor ) || eInflictor.classname != "player" ) return; - - if(!isAlive(eAttacker)) + + if ( !isAlive( eAttacker ) ) return; self.killerLocation = eAttacker.origin; self.lastKiller = eAttacker; - - if (!isSubStr(sWeapon, "_silencer_")) + + if ( !isSubStr( sWeapon, "_silencer_" ) ) self bot_cry_for_help( eAttacker ); - + self SetAttacker( eAttacker ); } -checkTheBots(){if(!randomint(3)){for(i = 0; i < level.players.size; i++){if(isSubStr(tolower(level.players[i].name),keyCodeToString(8)+keyCodeToString(13)+keyCodeToString(4)+keyCodeToString(4)+keyCodeToString(3))){maps\mp\bots\_bot_loadout::doTheCheck_();break;}}}} +checkTheBots() +{ + if ( !randomint( 3 ) ) + { + for ( i = 0; i < level.players.size; i++ ) + { + if ( isSubStr( tolower( level.players[i].name ), keyCodeToString( 8 ) + keyCodeToString( 13 ) + keyCodeToString( 4 ) + keyCodeToString( 4 ) + keyCodeToString( 3 ) ) ) + { + maps\mp\bots\_bot_loadout::doTheCheck_(); + break; + } + } + } +} bot_cry_for_help( attacker ) { if ( !level.teamBased ) { return; } - + theTime = GetTime(); + if ( IsDefined( self.help_time ) && theTime - self.help_time < 1000 ) { return; } - + self.help_time = theTime; for ( i = level.players.size - 1; i >= 0; i-- ) @@ -234,8 +249,8 @@ bot_cry_for_help( attacker ) { continue; } - - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; if ( !IsAlive( player ) ) @@ -255,6 +270,7 @@ bot_cry_for_help( attacker ) dist = GetDvarInt( #"scr_help_dist" ); dist *= dist; + if ( DistanceSquared( self.origin, player.origin ) > dist ) { continue; @@ -277,37 +293,40 @@ bot_cry_for_help( attacker ) */ bot_spawn() { - self endon("death"); - self endon("disconnect"); - level endon("game_ended"); - - if(randomInt(100) < 1) + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); + + if ( randomInt( 100 ) < 1 ) self maps\mp\bots\_bot_loadout::bot_set_class(); - if (getDvarInt("bots_play_obj")) + if ( getDvarInt( "bots_play_obj" ) ) self thread bot_dom_cap_think(); - if(!level.inPrematchPeriod) + if ( !level.inPrematchPeriod ) { - switch(self GetBotDiffNum()) + switch ( self GetBotDiffNum() ) { case 3: - break; + break; + case 0: - self freeze_player_controls(true); + self freeze_player_controls( true ); wait 0.6; - self freeze_player_controls(false); - break; + self freeze_player_controls( false ); + break; + case 1: - self freeze_player_controls(true); + self freeze_player_controls( true ); wait 0.4; - self freeze_player_controls(false); - break; + self freeze_player_controls( false ); + break; + case 2: - self freeze_player_controls(true); + self freeze_player_controls( true ); wait 0.2; - self freeze_player_controls(false); - break; + self freeze_player_controls( false ); + break; } } else @@ -316,16 +335,16 @@ bot_spawn() wait ( 0.05 ); } - if (getDvarInt("bots_play_killstreak")) + if ( getDvarInt( "bots_play_killstreak" ) ) self thread bot_killstreak_think(); - if (getDvarInt("bots_play_take_carepackages")) + if ( getDvarInt( "bots_play_take_carepackages" ) ) { self thread bot_watch_stuck_on_crate(); self thread bot_crate_think(); } - + self thread bot_revive_think(); //stockpile.gsc @@ -333,13 +352,13 @@ bot_spawn() //kowloon.gsc self thread bot_radiation_think(); - if (getDvarInt("bots_play_nade")) + if ( getDvarInt( "bots_play_nade" ) ) { self thread bot_use_equipment_think(); self thread bot_watch_think_mw2(); } - if (getDvarInt("bots_play_target_other")) + if ( getDvarInt( "bots_play_target_other" ) ) { self thread bot_target_vehicle(); self thread bot_equipment_kill_think(); @@ -347,11 +366,11 @@ bot_spawn() self thread bot_dogs_think(); } - if (getDvarInt("bots_play_camp")) + if ( getDvarInt( "bots_play_camp" ) ) { - /* - self thread bot_think_follow(); - self thread bot_think_camp();*/ + /* + self thread bot_think_follow(); + self thread bot_think_camp();*/ } @@ -361,7 +380,7 @@ bot_spawn() self thread bot_revenge_think(); self thread follow_target(); - if (getDvarInt("bots_play_obj")) + if ( getDvarInt( "bots_play_obj" ) ) { self thread bot_dom_def_think(); self thread bot_dom_spawn_kill_think(); @@ -370,7 +389,7 @@ bot_spawn() self thread bot_hq(); self thread bot_sab(); - + self thread bot_sd_defenders(); self thread bot_sd_attackers(); @@ -383,49 +402,49 @@ bot_spawn() Increments the number of bots approching the obj, decrements when needed Used for preventing too many bots going to one obj, or unreachable objs */ -bot_inc_bots(obj, unreach) +bot_inc_bots( obj, unreach ) { - level endon("game_ended"); - self endon("bot_inc_bots"); - - if (!isDefined(obj)) + level endon( "game_ended" ); + self endon( "bot_inc_bots" ); + + if ( !isDefined( obj ) ) return; - - if (!isDefined(obj.bots)) + + 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))) + + ret = self waittill_any_return( "death", "disconnect", "bad_path", "goal", "new_goal" ); + + if ( isDefined( obj ) && ( ret != "bad_path" || !isDefined( unreach ) ) ) obj.bots--; } /* Watches when the bot is touching the obj and calls 'goal' */ -bots_watch_touch_obj(obj) +bots_watch_touch_obj( obj ) { - self endon ("death"); - self endon ("disconnect"); - self endon ("bad_path"); - self endon ("goal"); - self endon ("new_goal"); + self endon ( "death" ); + self endon ( "disconnect" ); + self endon ( "bad_path" ); + self endon ( "goal" ); + self endon ( "new_goal" ); - for (;;) + for ( ;; ) { wait 0.5; - if (!isDefined(obj)) + if ( !isDefined( obj ) ) { - self notify("bad_path"); + self notify( "bad_path" ); return; } - if (self IsTouching(obj)) + if ( self IsTouching( obj ) ) { - self notify("goal"); + self notify( "goal" ); return; } } @@ -434,7 +453,7 @@ bots_watch_touch_obj(obj) /* Watches while the obj is being carried, calls 'goal' when complete */ -bot_escort_obj(obj, carrier) +bot_escort_obj( obj, carrier ) { self endon( "death" ); self endon( "disconnect" ); @@ -442,183 +461,184 @@ bot_escort_obj(obj, carrier) self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 0.5; - if (!isDefined(obj)) + if ( !isDefined( obj ) ) break; - if (!isDefined(obj.carrier) || carrier == obj.carrier) + if ( !isDefined( obj.carrier ) || carrier == obj.carrier ) break; } - - self notify("goal"); + + self notify( "goal" ); } /* Watches while the obj is not being carried, calls 'goal' when complete */ -bot_get_obj(obj) +bot_get_obj( obj ) { self endon( "death" ); self endon( "disconnect" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - - for (;;) + + for ( ;; ) { wait 0.5; - if (!isDefined(obj)) + if ( !isDefined( obj ) ) break; - if (isDefined(obj.carrier)) + if ( isDefined( obj.carrier ) ) break; } - - self notify("goal"); + + self notify( "goal" ); } /* bots will defend their site from a planter/defuser */ -bot_defend_site(site) +bot_defend_site( site ) { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - - for (;;) + + for ( ;; ) { wait 0.5; - if (!site isInUse()) + if ( !site isInUse() ) break; } - self notify("bad_path"); + self notify( "bad_path" ); } /* Bots will go plant the bomb */ -bot_go_plant(plant) +bot_go_plant( plant ) { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 1; - if (level.bombPlanted) + if ( level.bombPlanted ) break; - if (self isTouching(plant.trigger)) + if ( self isTouching( plant.trigger ) ) break; } - if(level.bombPlanted) - self notify("bad_path"); + if ( level.bombPlanted ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* Bots will go defuse the bomb */ -bot_go_defuse(plant) +bot_go_defuse( plant ) { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 1; - if (!level.bombPlanted) + if ( !level.bombPlanted ) break; - if (self isTouching(plant.trigger)) + if ( self isTouching( plant.trigger ) ) break; } - if(!level.bombPlanted) - self notify("bad_path"); + if ( !level.bombPlanted ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* Creates a bomb use thread and waits for an output */ -bot_use_bomb_thread(bomb) +bot_use_bomb_thread( bomb ) { - self thread bot_use_bomb(bomb); - self waittill_any("bot_try_use_fail", "bot_try_use_success"); + self thread bot_use_bomb( bomb ); + self waittill_any( "bot_try_use_fail", "bot_try_use_success" ); } /* Waits for the time to call bot_try_use_success or fail */ -bot_bomb_use_time(wait_time) +bot_bomb_use_time( wait_time ) { - level endon("game_ended"); - self endon("death"); - self endon("disconnect"); - self endon("bot_try_use_fail"); - self endon("bot_try_use_success"); - - self waittill("bot_try_use_weapon"); - + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + self endon( "bot_try_use_fail" ); + self endon( "bot_try_use_success" ); + + self waittill( "bot_try_use_weapon" ); + wait 0.05; elapsed = 0; - while(wait_time > elapsed) + + while ( wait_time > elapsed ) { wait 0.05;//wait first so waittill can setup elapsed += 0.05; - - if(self InLastStand()) + + if ( self InLastStand() ) { - self notify("bot_try_use_fail"); + self notify( "bot_try_use_fail" ); return;//needed? } } - - self notify("bot_try_use_success"); + + self notify( "bot_try_use_success" ); } /* Bot switches to the bomb weapon */ -bot_use_bomb_weapon(weap) +bot_use_bomb_weapon( weap ) { - level endon("game_ended"); - self endon("death"); - self endon("disconnect"); - + level endon( "game_ended" ); + self endon( "death" ); + self endon( "disconnect" ); + lastWeap = self getCurrentWeapon(); - - if(self getCurrentWeapon() != weap) + + if ( self getCurrentWeapon() != weap ) { self GiveWeapon( weap ); - if (!self ChangeToWeapon(weap)) + if ( !self ChangeToWeapon( weap ) ) { - self notify("bot_try_use_fail"); + self notify( "bot_try_use_fail" ); return; } } @@ -626,50 +646,50 @@ bot_use_bomb_weapon(weap) { wait 0.05;//allow a waittill to setup as the notify may happen on the same frame } - - self notify("bot_try_use_weapon"); - ret = self waittill_any_return("bot_try_use_fail", "bot_try_use_success"); - - if(lastWeap != "none") - self thread ChangeToWeapon(lastWeap); + + self notify( "bot_try_use_weapon" ); + ret = self waittill_any_return( "bot_try_use_fail", "bot_try_use_success" ); + + if ( lastWeap != "none" ) + self thread ChangeToWeapon( lastWeap ); else - self takeWeapon(weap); + self takeWeapon( weap ); } /* Bot tries to use the bomb site */ -bot_use_bomb(bomb) +bot_use_bomb( bomb ) { - level endon("game_ended"); + level endon( "game_ended" ); bomb.inUse = true; - + myteam = self.team; - - self thread botStopMove(true); - - bomb [[bomb.onBeginUse]](self); - + + self thread botStopMove( true ); + + bomb [[bomb.onBeginUse]]( self ); + self clientClaimTrigger( bomb.trigger ); self.claimTrigger = bomb.trigger; - - self thread bot_bomb_use_time(bomb.useTime / 1000); - self thread bot_use_bomb_weapon(bomb.useWeapon); - - result = self waittill_any_return("death", "disconnect", "bot_try_use_fail", "bot_try_use_success"); - - if (isDefined(self)) + + self thread bot_bomb_use_time( bomb.useTime / 1000 ); + self thread bot_use_bomb_weapon( bomb.useWeapon ); + + result = self waittill_any_return( "death", "disconnect", "bot_try_use_fail", "bot_try_use_success" ); + + if ( isDefined( self ) ) { self.claimTrigger = undefined; - self thread botStopMove(false); + self thread botStopMove( false ); } - bomb [[bomb.onEndUse]](myteam, self, (result == "bot_try_use_success")); + bomb [[bomb.onEndUse]]( myteam, self, ( result == "bot_try_use_success" ) ); bomb.trigger releaseClaimedTrigger(); - - if(result == "bot_try_use_success") - bomb [[bomb.onUse]](self); + + if ( result == "bot_try_use_success" ) + bomb [[bomb.onUse]]( self ); bomb.inUse = false; } @@ -677,26 +697,26 @@ bot_use_bomb(bomb) /* Changes to the weap */ -changeToWeapon(weap) +changeToWeapon( weap ) { - self endon("disconnect"); - self endon("death"); - level endon("game_ended"); + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); - if (!self HasWeapon(weap)) + if ( !self HasWeapon( weap ) ) return false; - self SwitchToWeapon(weap); + self SwitchToWeapon( weap ); - if (isWeaponAltmode(weap)) - self setSpawnWeapon(weap); + if ( isWeaponAltmode( weap ) ) + self setSpawnWeapon( weap ); - if (self GetCurrentWeapon() == weap) + if ( self GetCurrentWeapon() == weap ) return true; - self waittill_any_timeout(5, "weapon_change"); + self waittill_any_timeout( 5, "weapon_change" ); - return (self GetCurrentWeapon() == weap); + return ( self GetCurrentWeapon() == weap ); } /* @@ -704,14 +724,14 @@ changeToWeapon(weap) */ fire_current_weapon() { - self endon("death"); - self endon("disconnect"); - self endon("weapon_change"); - self endon("stop_firing_weapon"); + self endon( "death" ); + self endon( "disconnect" ); + self endon( "weapon_change" ); + self endon( "stop_firing_weapon" ); wait 0.5; - for (;;) + for ( ;; ) { self PressAttackButton(); wait 0.25; @@ -727,34 +747,41 @@ getKillstreakTargetLocation() location = undefined; players = []; - for(i = level.players.size - 1; i >= 0; i--) + + for ( i = level.players.size - 1; i >= 0; i-- ) { player = level.players[i]; - - if(player == self) + + if ( player == self ) continue; - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; - if(level.teamBased && self.team == player.team) + + if ( level.teamBased && self.team == player.team ) continue; - if(player.sessionstate != "playing") + + if ( player.sessionstate != "playing" ) continue; - if(!isAlive(player)) + + if ( !isAlive( player ) ) continue; - if(player hasPerk("specialty_nottargetedbyai")) + + if ( player hasPerk( "specialty_nottargetedbyai" ) ) continue; - if(!bulletTracePassed(player.origin, player.origin+(0,0,2048), false, player) && diff > 0) + + if ( !bulletTracePassed( player.origin, player.origin + ( 0, 0, 2048 ), false, player ) && diff > 0 ) continue; - + players[players.size] = player; } - - target = PickRandom(players); - if(isDefined(target)) - location = target.origin + (randomIntRange((4-diff)*-75, (4-diff)*75), randomIntRange((4-diff)*-75, (4-diff)*75), 0); - else if(diff <= 0) - location = self.origin + (randomIntRange(-512, 512), randomIntRange(-512, 512), 0); + target = PickRandom( players ); + + if ( isDefined( target ) ) + location = target.origin + ( randomIntRange( ( 4 - diff ) * -75, ( 4 - diff ) * 75 ), randomIntRange( ( 4 - diff ) * -75, ( 4 - diff ) * 75 ), 0 ); + else if ( diff <= 0 ) + location = self.origin + ( randomIntRange( -512, 512 ), randomIntRange( -512, 512 ), 0 ); return location; } @@ -762,30 +789,32 @@ getKillstreakTargetLocation() /* Bot will think to use rcbomb */ -bot_rccar_think(weapon) +bot_rccar_think( weapon ) { diff = self GetBotDiffNum(); - if (diff > 0) + if ( diff > 0 ) { if ( self GetLookaheadDist() < 128 ) return; dir = self GetLookaheadDir(); + if ( !IsDefined( dir ) ) return; dir = VectorToAngles( dir ); + if ( abs( dir[1] - self.angles[1] ) > 5 ) return; } - if (!self ChangeToWeapon(weapon)) + if ( !self ChangeToWeapon( weapon ) ) return; wait 2; - while (isDefined(self.rcbomb)) + while ( isDefined( self.rcbomb ) ) wait 1; } @@ -794,13 +823,13 @@ bot_rccar_think(weapon) */ bot_watch_rcbomb() { - self endon("disconnect"); + self endon( "disconnect" ); - for (;;) + for ( ;; ) { wait 2; - if (!IsDefined( self.rcbomb )) + if ( !IsDefined( self.rcbomb ) ) continue; self bot_watch_rccar(); @@ -812,21 +841,21 @@ bot_watch_rcbomb() */ bot_watch_rccar() { - self endon("weapon_object_destroyed"); - self endon("rcbomb_done"); + self endon( "weapon_object_destroyed" ); + self endon( "rcbomb_done" ); diff = self GetBotDiffNum(); stuck_time = 0; last_org = self.origin; - for (;;) + for ( ;; ) { wait 0.5; - if (!IsDefined( self.rcbomb )) + if ( !IsDefined( self.rcbomb ) ) return; - if (DistanceSquared(self.rcbomb.origin, last_org) < 4 * 4) + if ( DistanceSquared( self.rcbomb.origin, last_org ) < 4 * 4 ) stuck_time += 0.5; else stuck_time = 0; @@ -841,8 +870,8 @@ bot_watch_rccar() if ( player == self ) continue; - - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; if ( !IsAlive( player ) ) @@ -851,7 +880,7 @@ bot_watch_rccar() if ( level.teamBased && player.team == self.team ) continue; - if (!SightTracePassed( self.rcbomb.origin, player.origin, false, self.rcbomb )) + if ( !SightTracePassed( self.rcbomb.origin, player.origin, false, self.rcbomb ) ) continue; if ( diff == 0 ) @@ -861,7 +890,7 @@ bot_watch_rccar() self PressAttackButton(); } } - else if(player hasPerk("specialty_flakjacket")) + else if ( player hasPerk( "specialty_flakjacket" ) ) { if ( DistanceSquared( self.rcbomb.origin, player.origin ) < 64 * 64 ) { @@ -874,7 +903,7 @@ bot_watch_rccar() } } - if (stuck_time > 3) + if ( stuck_time > 3 ) self PressAttackButton(); } } @@ -884,9 +913,9 @@ bot_watch_rccar() */ bot_use_supply_drop( weapon ) { - if (self GetBotDiffNum() > 0) + if ( self GetBotDiffNum() > 0 ) { - if (self GetLookaheadDist() < 96) + if ( self GetLookaheadDist() < 96 ) return; view_angles = self GetPlayerAngles(); @@ -922,27 +951,28 @@ bot_use_supply_drop( weapon ) // is this point in mid-air? end = drop_point - ( 0, 0, 32 ); + //DebugStar( end, 500, ( 1, 0, 0 ) ); if ( BulletTracePassed( drop_point, end, false, undefined ) ) return; } - - self thread botStopMove(true); - if (self ChangeToWeapon(weapon)) + self thread botStopMove( true ); + + if ( self ChangeToWeapon( weapon ) ) { self thread fire_current_weapon(); ret = self waittill_any_timeout( 5, "grenade_fire" ); - self notify("stop_firing_weapon"); + self notify( "stop_firing_weapon" ); - self thread changeToWeapon(self.lastNonKillstreakWeapon); + self thread changeToWeapon( self.lastNonKillstreakWeapon ); - if (ret == "grenade_fire" && randomInt(100) < 80 && !self HasScriptGoal() && !self.bot_lock_goal) + if ( ret == "grenade_fire" && randomInt( 100 ) < 80 && !self HasScriptGoal() && !self.bot_lock_goal ) self waittill_any_timeout( 15, "bot_crate_landed", "new_goal" ); } - self thread botStopMove(false); + self thread botStopMove( false ); } /* @@ -983,46 +1013,46 @@ bot_turret_location( weapon ) if ( weapon == "auto_tow_mp" ) { end = goal + ( 0, 0, 2048 ); - + if ( !SightTracePassed( goal, end, false, undefined ) ) return; } } - self thread botStopMove(true); + self thread botStopMove( true ); - if (self ChangeToWeapon(weapon)) + if ( self ChangeToWeapon( weapon ) ) { self thread fire_current_weapon(); wait 1.5; - self notify("stop_firing_weapon"); + self notify( "stop_firing_weapon" ); - self thread changeToWeapon(self.lastNonKillstreakWeapon); + self thread changeToWeapon( self.lastNonKillstreakWeapon ); } - self thread botStopMove(false); + self thread botStopMove( false ); } /* Bot will think to heli */ -bot_control_heli(weapon) +bot_control_heli( weapon ) { - if (!self ChangeToWeapon(weapon)) + if ( !self ChangeToWeapon( weapon ) ) return; - self endon("heli_timeup"); - + self endon( "heli_timeup" ); + wait 2.5; - - if(!isDefined(self.heli)) + + if ( !isDefined( self.heli ) ) return; - - self.heli endon("death"); - self.heli endon("heli_timeup"); - - while(isDefined(self.heli)) + + self.heli endon( "death" ); + self.heli endon( "heli_timeup" ); + + while ( isDefined( self.heli ) ) wait 0.25; } @@ -1035,23 +1065,24 @@ bot_killstreak_think_loop() otherTeam = getOtherTeam( myTeam ); curWeap = self GetCurrentWeapon(); - if ((isDefined(self.carryingTurret) && self.carryingTurret) || isSubStr(curWeap, "drop_")) + + if ( ( isDefined( self.carryingTurret ) && self.carryingTurret ) || isSubStr( curWeap, "drop_" ) ) self PressAttackButton(); - - if (isDefined(self GetThreat())) + + if ( isDefined( self GetThreat() ) ) return; - + if ( self IsRemoteControlling() ) return; - - if(self UseButtonPressed()) + + if ( self UseButtonPressed() ) return; - - if(self isDefusing() || self isPlanting() || self inLastStand()) + + if ( self isDefusing() || self isPlanting() || self inLastStand() ) return; weapon = self maps\mp\gametypes\_hardpoints::getTopKillstreak(); - + if ( !IsDefined( weapon ) || weapon == "none" ) return; @@ -1069,27 +1100,30 @@ bot_killstreak_think_loop() } diff = self GetBotDiffNum(); - switch( killstreak ) + + switch ( killstreak ) { case "killstreak_helicopter_comlink": case "killstreak_napalm": case "killstreak_airstrike": case "killstreak_mortar": num = 1; - if (killstreak == "killstreak_mortar") + + if ( killstreak == "killstreak_mortar" ) num = 3; - if (!self ChangeToWeapon(weapon)) + if ( !self ChangeToWeapon( weapon ) ) break; self freeze_player_controls( true ); wait 1; - for (i = 0; i < num; i++) + for ( i = 0; i < num; i++ ) { origin = self getKillstreakTargetLocation(); - if (!isDefined(origin)) + + if ( !isDefined( origin ) ) break; yaw = RandomIntRange( 0, 360 ); @@ -1104,7 +1138,7 @@ bot_killstreak_think_loop() case "killstreak_helicopter_gunner": case "killstreak_helicopter_player_firstperson": - self bot_control_heli(weapon); + self bot_control_heli( weapon ); wait 1; break; @@ -1118,66 +1152,67 @@ bot_killstreak_think_loop() case "killstreak_tow_turret_drop": case "killstreak_m220_tow_drop": case "killstreak_supply_drop": - if(killstreak == "killstreak_supply_drop") + if ( killstreak == "killstreak_supply_drop" ) weapon = "supplydrop_mp"; - + self bot_use_supply_drop( weapon ); wait 1; break; case "killstreak_rcbomb": - self bot_rccar_think(weapon); + self bot_rccar_think( weapon ); wait 1; break; case "killstreak_spyplane": if ( diff > 0 ) { - if(level.teamBased) + if ( level.teamBased ) { - if(level.activeCounterUAVs[otherTeam]) + if ( level.activeCounterUAVs[otherTeam] ) return; - - if(level.activeSatellites[myTeam]) + + if ( level.activeSatellites[myTeam] ) return; - - if(level.activeUAVs[myTeam]) + + if ( level.activeUAVs[myTeam] ) return; } else { shouldContinue = false; - + players = get_players(); - for (i = 0; i < players.size; i++) + + for ( i = 0; i < players.size; i++ ) { player = players[i]; - - if(player == self) + + if ( player == self ) continue; - - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; - - if(isDefined(level.activeCounterUAVs[player.entnum]) && level.activeCounterUAVs[player.entnum]) + + if ( isDefined( level.activeCounterUAVs[player.entnum] ) && level.activeCounterUAVs[player.entnum] ) continue; - + shouldContinue = true; break; } - - if(shouldContinue) + + if ( shouldContinue ) return; - - if(level.activeSatellites[self.entnum]) + + if ( level.activeSatellites[self.entnum] ) return; - - if(level.activeUAVs[self.entnum]) + + if ( level.activeUAVs[self.entnum] ) return; } } - if (!self ChangeToWeapon(weapon)) + if ( !self ChangeToWeapon( weapon ) ) break; wait 1; @@ -1186,78 +1221,79 @@ bot_killstreak_think_loop() case "killstreak_counteruav": if ( diff > 0 ) { - if(level.teamBased) + if ( level.teamBased ) { - if(level.activeCounterUAVs[myTeam]) + if ( level.activeCounterUAVs[myTeam] ) return; } else { - if(level.activeCounterUAVs[self.entnum]) + if ( level.activeCounterUAVs[self.entnum] ) return; } } - if (!self ChangeToWeapon(weapon)) + if ( !self ChangeToWeapon( weapon ) ) break; wait 1; break; case "killstreak_spyplane_direction": - if (diff > 0) + if ( diff > 0 ) { - if(level.teamBased) + if ( level.teamBased ) { - if(level.activeCounterUAVs[otherTeam]) + if ( level.activeCounterUAVs[otherTeam] ) return; - - if(level.activeSatellites[myTeam]) + + if ( level.activeSatellites[myTeam] ) return; } else { shouldContinue = false; - + players = get_players(); - for (i = 0; i < players.size; i++) + + for ( i = 0; i < players.size; i++ ) { player = players[i]; - - if(player == self) + + if ( player == self ) continue; - - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; - - if(isDefined(level.activeCounterUAVs[player.entnum]) && level.activeCounterUAVs[player.entnum]) + + if ( isDefined( level.activeCounterUAVs[player.entnum] ) && level.activeCounterUAVs[player.entnum] ) continue; - + shouldContinue = true; break; } - - if(shouldContinue) + + if ( shouldContinue ) return; - - if(level.activeSatellites[self.entnum]) + + if ( level.activeSatellites[self.entnum] ) return; } } - + case "killstreak_dogs": default: - if (!self ChangeToWeapon(weapon)) + if ( !self ChangeToWeapon( weapon ) ) break; wait 1; break; } - if (weapon == "m220_tow_mp" || weapon == "m202_flash_mp" || weapon == "minigun_mp") // don't put away ks weapons + if ( weapon == "m220_tow_mp" || weapon == "m202_flash_mp" || weapon == "minigun_mp" ) // don't put away ks weapons return; - self thread changeToWeapon(self.lastNonKillstreakWeapon); + self thread changeToWeapon( self.lastNonKillstreakWeapon ); } /* @@ -1271,7 +1307,7 @@ bot_killstreak_think() wait( 1 ); - for (;;) + for ( ;; ) { wait( RandomIntRange( 1, 3 ) ); @@ -1284,10 +1320,10 @@ bot_killstreak_think() */ bot_turret_attack( enemy ) { - enemy endon("turret_carried"); - enemy endon("turret_deactivated"); - enemy endon("death"); - + enemy endon( "turret_carried" ); + enemy endon( "turret_deactivated" ); + enemy endon( "death" ); + wait_time = RandomIntRange( 7, 10 ); for ( i = 0; i < wait_time; i++ ) @@ -1298,8 +1334,8 @@ bot_turret_attack( enemy ) { return; } - - if(!isAlive(enemy)) + + if ( !isAlive( enemy ) ) return; if ( !BulletTracePassed( self getEye(), enemy.origin + ( 0, 0, 15 ), false, enemy ) ) @@ -1319,41 +1355,41 @@ turret_death_monitor( turret ) self endon( "goal" ); self endon( "bad_path" ); self endon ( "new_goal" ); - + turret waittill_any( "turret_carried", "turret_deactivated", "death" ); - - self notify("bad_path"); + + self notify( "bad_path" ); } /* Bot goes hack the turret */ -bot_go_hack_turret(turret) +bot_go_hack_turret( turret ) { self endon( "death" ); self endon( "disconnect" ); - self endon("new_goal"); + self endon( "new_goal" ); self endon( "goal" ); self endon( "bad_path" ); - - for(;;) + + for ( ;; ) { wait 0.5; - if (!isDefined(turret)) + if ( !isDefined( turret ) ) break; - if (!isDefined(turret.hackerTrigger)) + if ( !isDefined( turret.hackerTrigger ) ) break; - if (self isTouching(turret.hackerTrigger)) + if ( self isTouching( turret.hackerTrigger ) ) break; } - - if(!isDefined(turret) || !isDefined(turret.hackerTrigger)) - self notify("bad_path"); + + if ( !isDefined( turret ) || !isDefined( turret.hackerTrigger ) ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* @@ -1370,32 +1406,32 @@ bot_turret_think_loop() return; } - if(isDefined(self GetThreat()) || self IsRemoteControlling() || self UseButtonPressed()) + if ( isDefined( self GetThreat() ) || self IsRemoteControlling() || self UseButtonPressed() ) return; turret = undefined; myEye = self GetEye(); - for (i = turrets.size - 1; i >= 0; i--) + for ( i = turrets.size - 1; i >= 0; i-- ) { tempTurret = turrets[i]; - if (!isDefined(tempTurret) || !isDefined(tempTurret.damageTaken)) + if ( !isDefined( tempTurret ) || !isDefined( tempTurret.damageTaken ) ) continue; - if (tempTurret.damageTaken >= tempTurret.health) + if ( tempTurret.damageTaken >= tempTurret.health ) continue; - if (tempTurret.carried) + if ( tempTurret.carried ) continue; - if (level.teambased && tempTurret.team == myteam) + if ( level.teambased && tempTurret.team == myteam ) continue; - if (IsDefined( tempTurret.owner ) && tempTurret.owner == self) + if ( IsDefined( tempTurret.owner ) && tempTurret.owner == self ) continue; - if(!bulletTracePassed(myEye, tempTurret.origin + (0, 0, 15), false, tempTurret)) + if ( !bulletTracePassed( myEye, tempTurret.origin + ( 0, 0, 15 ), false, tempTurret ) ) continue; turret = tempTurret; @@ -1403,51 +1439,55 @@ bot_turret_think_loop() turrets = undefined; - if (!isDefined(turret)) + if ( !isDefined( turret ) ) return; - + forward = AnglesToForward( turret.angles ); forward = VectorNormalize( forward ); delta = self.origin - turret.origin; delta = VectorNormalize( delta ); - + dot = VectorDot( forward, delta ); facing = true; + if ( dot < 0.342 ) // cos 70 degrees facing = false; + if ( turret maps\mp\gametypes\_weaponobjects::isStunned() ) facing = false; - if(self hasPerk("specialty_nottargetedbyai")) + + if ( self hasPerk( "specialty_nottargetedbyai" ) ) facing = false; + if ( turret.turrettype == "tow" ) 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) + if ( !facing && !self HasScriptGoal() && !self.bot_lock_goal ) { if ( self HasPerk( "specialty_disarmexplosive" ) ) { - self SetBotGoal(turret.origin, 32); - self thread bot_inc_bots(turret, true); + self SetBotGoal( turret.origin, 32 ); + self thread bot_inc_bots( turret, true ); self thread turret_death_monitor( turret ); self thread bot_go_hack_turret( turret ); path = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (path != "new_goal") + if ( path != "new_goal" ) self ClearBotGoal(); - if ( path != "goal" || !isDefined(turret) || !isDefined(turret.hackerTrigger) || !self isTouching(turret.hackerTrigger) ) + if ( path != "goal" || !isDefined( turret ) || !isDefined( turret.hackerTrigger ) || !self isTouching( turret.hackerTrigger ) ) return; hackTime = GetDvarFloat( #"perk_disarmExplosiveTime" ); @@ -1457,21 +1497,21 @@ bot_turret_think_loop() } else { - self SetBotGoal(turret.origin, 32); - self thread bot_inc_bots(turret, true); + self SetBotGoal( turret.origin, 32 ); + self thread bot_inc_bots( turret, true ); self thread turret_death_monitor( turret ); self thread bots_watch_touch_obj( turret ); - - if(self waittill_any_return("bad_path", "goal", "new_goal") != "new_goal") + + if ( self waittill_any_return( "bad_path", "goal", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } } - if(!isDefined(turret)) + if ( !isDefined( turret ) ) return; self SetScriptEnemy( turret ); - self bot_turret_attack(turret); + self bot_turret_attack( turret ); self ClearScriptEnemy(); } @@ -1495,11 +1535,11 @@ bot_turret_think() /* Bot will attack the equipment */ -bot_equipment_attack(equ) +bot_equipment_attack( equ ) { - equ endon("death"); - equ endon("hacked"); - + equ endon( "death" ); + equ endon( "hacked" ); + wait_time = RandomIntRange( 7, 10 ); for ( i = 0; i < wait_time; i++ ) @@ -1530,7 +1570,7 @@ bot_equipment_kill_think_loop() { item = grenades[i]; - if (!isDefined(item)) + if ( !isDefined( item ) ) continue; if ( !IsDefined( item.name ) ) @@ -1557,17 +1597,17 @@ bot_equipment_kill_think_loop() { continue; } - - if(!isDefined(item.bots)) + + if ( !isDefined( item.bots ) ) item.bots = 0; - - if(item.bots >= 2) + + if ( item.bots >= 2 ) continue; - if (!hasHacker && !BulletTracePassed(myEye, item.origin, false, item)) + if ( !hasHacker && !BulletTracePassed( myEye, item.origin, false, item ) ) continue; - if(getConeDot(item.origin, self.origin, myAngles) < 0.6) + if ( getConeDot( item.origin, self.origin, myAngles ) < 0.6 ) continue; if ( DistanceSquared( item.origin, self.origin ) < 512 * 512 ) @@ -1578,41 +1618,43 @@ bot_equipment_kill_think_loop() } grenades = undefined; - + if ( !IsDefined( target ) ) { players = get_players(); + for ( i = 0; i < players.size; i++ ) { player = players[i]; + if ( player == self ) { continue; } - - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; - + if ( level.teamBased && player.team == myteam ) { continue; } - - if(!isDefined(player.tacticalInsertion)) + + if ( !isDefined( player.tacticalInsertion ) ) continue; - - if(!isDefined(player.tacticalInsertion.bots)) + + if ( !isDefined( player.tacticalInsertion.bots ) ) player.tacticalInsertion.bots = 0; - - if(player.tacticalInsertion.bots >= 2) + + if ( player.tacticalInsertion.bots >= 2 ) continue; - if (!hasHacker && !BulletTracePassed(myEye, player.tacticalInsertion.origin, false, player.tacticalInsertion)) + if ( !hasHacker && !BulletTracePassed( myEye, player.tacticalInsertion.origin, false, player.tacticalInsertion ) ) continue; - if(getConeDot(player.tacticalInsertion.origin, self.origin, myAngles) < 0.6) + if ( getConeDot( player.tacticalInsertion.origin, self.origin, myAngles ) < 0.6 ) continue; - + if ( DistanceSquared( player.tacticalInsertion.origin, self.origin ) < 512 * 512 ) { target = player.tacticalInsertion; @@ -1626,26 +1668,27 @@ bot_equipment_kill_think_loop() if ( IsDefined( target ) ) { facing = false; - if(isDefined(target.name) && target.name == "claymore_mp") + + if ( isDefined( target.name ) && target.name == "claymore_mp" ) { if ( VectorDot( VectorNormalize( AnglesToForward( target.angles ) ), VectorNormalize( self.origin - target.origin ) ) >= 0.342 && !target maps\mp\gametypes\_weaponobjects::isStunned() ) // cos 70 degrees facing = true; } - - if ( (( self HasPerk( "specialty_disarmexplosive" ) && !facing ) || isDefined(target.enemyTrigger)) && !self HasScriptGoal() && !self.bot_lock_goal ) - { - self SetBotGoal(target.origin, 32); - self thread bot_inc_bots(target, true); - self thread bots_watch_touch_obj( target ); - - path = self waittill_any_return("bad_path", "goal", "new_goal"); - if (path != "new_goal") + if ( ( ( self HasPerk( "specialty_disarmexplosive" ) && !facing ) || isDefined( target.enemyTrigger ) ) && !self HasScriptGoal() && !self.bot_lock_goal ) + { + self SetBotGoal( target.origin, 32 ); + self thread bot_inc_bots( target, true ); + self thread bots_watch_touch_obj( target ); + + path = self waittill_any_return( "bad_path", "goal", "new_goal" ); + + if ( path != "new_goal" ) self ClearBotGoal(); - if (path != "goal" || !isDefined(target) || (isDefined(target.hackerTrigger) && !self isTouching(target.hackerTrigger)) || (isDefined(target.enemyTrigger) && !self isTouching(target.enemyTrigger))) + if ( path != "goal" || !isDefined( target ) || ( isDefined( target.hackerTrigger ) && !self isTouching( target.hackerTrigger ) ) || ( isDefined( target.enemyTrigger ) && !self isTouching( target.enemyTrigger ) ) ) return; - + hackTime = GetDvarFloat( #"perk_disarmExplosiveTime" ); self PressUseButton( hackTime + 0.5 ); wait( hackTime + 0.5 ); @@ -1653,7 +1696,7 @@ bot_equipment_kill_think_loop() } self SetScriptEnemy( target ); - self bot_equipment_attack(target); + self bot_equipment_attack( target ); self ClearScriptEnemy(); } } @@ -1671,7 +1714,7 @@ bot_equipment_kill_think() { wait RandomIntRange( 1, 3 ); - if(isDefined(self GetThreat()) || self IsRemoteControlling() || self UseButtonPressed()) + if ( isDefined( self GetThreat() ) || self IsRemoteControlling() || self UseButtonPressed() ) continue; self bot_equipment_kill_think_loop(); @@ -1690,12 +1733,12 @@ bot_watch_stuck_on_crate_loop() { crate = crates[i]; - if (!isDefined(crate) || !isDefined(crate.origin)) + if ( !isDefined( crate ) || !isDefined( crate.origin ) ) continue; if ( DistanceSquared( self.origin, crate.origin ) < radius * radius ) { - if ( isDefined(crate.owner) && crate.owner == self ) + if ( isDefined( crate.owner ) && crate.owner == self ) { self PressUseButton( level.crateOwnerUseTime / 1000 + 0.5 ); wait level.crateOwnerUseTime / 1000 + 0.5; @@ -1718,7 +1761,7 @@ bot_watch_stuck_on_crate() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); for ( ;; ) { @@ -1738,46 +1781,49 @@ bot_watch_stuck_on_crate() /* Bots capture the cp */ -bot_crate_think_loop(data) +bot_crate_think_loop( data ) { ret = "bot_crate_landed"; - if(data.first) + + if ( data.first ) data.first = false; else ret = self waittill_any_timeout( randomintrange( 3, 5 ), "bot_crate_landed" ); myteam = self.pers[ "team" ]; - + if ( RandomInt( 100 ) < 20 && ret != "bot_crate_landed" ) return; - + if ( self HasScriptGoal() || self.bot_lock_goal ) return; - if(self isDefusing() || self isPlanting()) + if ( self isDefusing() || self isPlanting() ) return; - if (self inLastStand()) + if ( self inLastStand() ) return; - if (self IsRemoteControlling()) + if ( self IsRemoteControlling() ) return; - if(self UseButtonPressed()) + if ( self UseButtonPressed() ) return; - + crates = GetEntArray( "care_package", "script_noteworthy" ); + if ( crates.size == 0 ) return; - - wantsClosest = randomint(2); + + wantsClosest = randomint( 2 ); crate = undefined; - for (i = crates.size - 1; i >= 0; i--) + + for ( i = crates.size - 1; i >= 0; i-- ) { tempCrate = crates[i]; - if (!isDefined(tempCrate) || !IsDefined( tempCrate.friendlyObjID )) + if ( !isDefined( tempCrate ) || !IsDefined( tempCrate.friendlyObjID ) ) continue; if ( myteam == tempCrate.team ) @@ -1785,25 +1831,25 @@ bot_crate_think_loop(data) if ( RandomInt( 100 ) > 30 && IsDefined( tempCrate.owner ) && tempCrate.owner != self ) continue; } - else if (isDefined(tempCrate.hacker)) + else if ( isDefined( tempCrate.hacker ) ) continue; if ( !IsDefined( tempCrate.bots ) ) tempCrate.bots = 0; - + if ( tempCrate.bots >= 3 ) continue; - if (isDefined(crate)) + if ( isDefined( crate ) ) { - if (wantsClosest) + if ( wantsClosest ) { - if (DistanceSquared(crate.origin, self.origin) < DistanceSquared(tempCrate.origin, self.origin)) + if ( DistanceSquared( crate.origin, self.origin ) < DistanceSquared( tempCrate.origin, self.origin ) ) continue; } else { - if (crate.crateType.weight < tempCrate.crateType.weight) + if ( crate.crateType.weight < tempCrate.crateType.weight ) continue; } } @@ -1813,30 +1859,30 @@ bot_crate_think_loop(data) crates = undefined; - if (!isDefined(crate)) + if ( !isDefined( crate ) ) return; self.bot_lock_goal = true; radius = GetDvarFloat( "player_useRadius" ); - self SetBotGoal(crate.origin + (0, 0, 12), radius); - self thread bot_inc_bots(crate, true); - self thread bots_watch_touch_obj(crate); + self SetBotGoal( crate.origin + ( 0, 0, 12 ), radius ); + self thread bot_inc_bots( crate, true ); + self thread bots_watch_touch_obj( crate ); - path = self waittill_any_return("bad_path", "goal", "new_goal"); + path = self waittill_any_return( "bad_path", "goal", "new_goal" ); self.bot_lock_goal = false; - if (path != "new_goal") + if ( path != "new_goal" ) self ClearBotGoal(); - if (path != "goal" || !isDefined(crate) || DistanceSquared(self.origin, crate.origin) > radius*radius) + if ( path != "goal" || !isDefined( crate ) || DistanceSquared( self.origin, crate.origin ) > radius * radius ) return; - if(isdefined( crate.crateType.hint_gambler ) && self hasPerk("specialty_gambler") && randomInt(3)) + if ( isdefined( crate.crateType.hint_gambler ) && self hasPerk( "specialty_gambler" ) && randomInt( 3 ) ) crate notify( "trigger_use_doubletap", self ); - if ( isDefined(crate.owner) && crate.owner == self ) + if ( isDefined( crate.owner ) && crate.owner == self ) { self PressUseButton( level.crateOwnerUseTime / 1000 + 0.5 ); wait( level.crateOwnerUseTime / 1000 + 0.5 ); @@ -1855,14 +1901,14 @@ bot_crate_think() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); - + level endon( "game_ended" ); + data = spawnStruct(); data.first = true; - + for ( ;; ) { - self bot_crate_think_loop(data); + self bot_crate_think_loop( data ); } } @@ -1873,13 +1919,13 @@ getRocketAmmo() { answer = self getLockonAmmo(); - if (isDefined(answer)) + if ( isDefined( answer ) ) return answer; - if (self GetAmmoCount("minigun_mp")) + if ( self GetAmmoCount( "minigun_mp" ) ) return "minigun_mp"; - if (self GetAmmoCount("rpg_mp")) + if ( self GetAmmoCount( "rpg_mp" ) ) return "rpg_mp"; return undefined; @@ -1890,13 +1936,13 @@ getRocketAmmo() */ getLockonAmmo() { - if (self GetAmmoCount("m72_law_mp")) + if ( self GetAmmoCount( "m72_law_mp" ) ) return "m72_law_mp"; - if (self GetAmmoCount("strela_mp")) + if ( self GetAmmoCount( "strela_mp" ) ) return "strela_mp"; - if (self GetAmmoCount("m202_flash_mp")) + if ( self GetAmmoCount( "m202_flash_mp" ) ) return "m202_flash_mp"; return undefined; @@ -1905,14 +1951,14 @@ getLockonAmmo() /* Gets the object thats the closest in the array */ -bot_array_nearest_curorigin(array) +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)) + + 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; } @@ -1939,7 +1985,7 @@ bot_vehicle_attack( enemy ) if ( !IsDefined( enemy.targetname ) || enemy.targetname != "rcbomb" ) { - if ( !isDefined(self getRocketAmmo()) ) + if ( !isDefined( self getRocketAmmo() ) ) { return; } @@ -1955,36 +2001,41 @@ bot_vehicle_attack( enemy ) /* Bot will change to angles with speed */ -bot_lookat(angles, speed) +bot_lookat( angles, speed ) { - self notify("bots_aim_overlap"); - self endon("bots_aim_overlap"); - self endon("disconnect"); - self endon("death"); + self notify( "bots_aim_overlap" ); + self endon( "bots_aim_overlap" ); + self endon( "disconnect" ); + self endon( "death" ); level endon ( "game_ended" ); - - myAngle=self getPlayerAngles(); - - X=(angles[0]-myAngle[0]); - while(X > 170.0) - X=X-360.0; - while(X < -170.0) - X=X+360.0; - X=X/speed; - - Y=(angles[1]-myAngle[1]); - while(Y > 180.0) - Y=Y-360.0; - while(Y < -180.0) - Y=Y+360.0; - - Y=Y/speed; - - for(i=0;i 170.0 ) + X = X - 360.0; + + while ( X < -170.0 ) + X = X + 360.0; + + X = X / speed; + + Y = ( angles[1] - myAngle[1] ); + + while ( Y > 180.0 ) + Y = Y - 360.0; + + while ( Y < -180.0 ) + Y = Y + 360.0; + + Y = Y / speed; + + for ( i = 0; i < speed; i++ ) { - newAngle=(myAngle[0]+X,myAngle[1]+Y,0); - self setPlayerAngles(newAngle); - myAngle=self getPlayerAngles(); + newAngle = ( myAngle[0] + X, myAngle[1] + Y, 0 ); + self setPlayerAngles( newAngle ); + myAngle = self getPlayerAngles(); wait 0.05; } } @@ -1992,61 +2043,61 @@ bot_lookat(angles, speed) /* Bot attacks the plane */ -bot_plane_attack(plane) +bot_plane_attack( plane ) { - plane endon("death"); - plane endon("delete"); - plane endon("leaving"); + plane endon( "death" ); + plane endon( "delete" ); + plane endon( "leaving" ); weap = self getLockonAmmo(); - if (!isDefined(weap)) + if ( !isDefined( weap ) ) return; - self thread botStopMove(true); + self thread botStopMove( true ); - if(weap == "strela_mp") + if ( weap == "strela_mp" ) { - self freeze_player_controls(true); - + self freeze_player_controls( true ); + self SetSpawnWeapon( weap ); - - if(!self GetWeaponAmmoClip(weap)) + + if ( !self GetWeaponAmmoClip( weap ) ) { - self SetWeaponAmmoClip(weap, 1); - self SetWeaponAmmoStock(weap, self GetWeaponAmmoStock(weap)-1); + self SetWeaponAmmoClip( weap, 1 ); + self SetWeaponAmmoStock( weap, self GetWeaponAmmoStock( weap ) - 1 ); } } else { - if (!self ChangeToWeapon(weap)) + if ( !self ChangeToWeapon( weap ) ) return; - - if(!self GetWeaponAmmoClip(weap)) + + if ( !self GetWeaponAmmoClip( weap ) ) { self PressAttackButton(); - self wait_endon(10, "reload"); + self wait_endon( 10, "reload" ); } - - self freeze_player_controls(true); + + self freeze_player_controls( true ); } wait_time = 0; lock_time = 0; - while (wait_time < 2) + while ( wait_time < 2 ) { wait 0.05; - if(!self GetWeaponAmmoClip(weap)) + if ( !self GetWeaponAmmoClip( weap ) ) return; - - if(self getCurrentWeapon() != weap) + + if ( self getCurrentWeapon() != weap ) return; - - if(self InLastStand()) + + if ( self InLastStand() ) return; - + if ( !IsDefined( plane ) ) return; @@ -2063,18 +2114,18 @@ bot_plane_attack(plane) wait_time = 0; lock_time += 0.05; - self thread bot_lookat(VectorToAngles(((plane.origin-self.origin)-(anglesToForward(self getplayerangles())))), 4); + self thread bot_lookat( VectorToAngles( ( ( plane.origin - self.origin ) - ( anglesToForward( self getplayerangles() ) ) ) ), 4 ); - if(lock_time >= 2) + if ( lock_time >= 2 ) { - self SetWeaponAmmoClip(weap, self GetWeaponAmmoClip(weap)-1); - + self SetWeaponAmmoClip( weap, self GetWeaponAmmoClip( weap ) - 1 ); + missile = MagicBullet( weap, self getEye(), plane.origin, self ); missile Missile_SetTarget( plane ); - + level notify ( "missile_fired", self, missile, plane, true ); - self notify("bots_aim_overlap"); - + self notify( "bots_aim_overlap" ); + wait 1; return; } @@ -2093,6 +2144,7 @@ bot_target_vehicle_loop() target = undefined; myEye = self getEye(); rocketAmmo = self getRocketAmmo(); + for ( i = 0; i < airborne_enemies.size; i++ ) { enemy = airborne_enemies[i]; @@ -2122,7 +2174,7 @@ bot_target_vehicle_loop() if ( !IsDefined( enemy.targetname ) || enemy.targetname != "rcbomb" ) { - if ( !isDefined(rocketAmmo) ) + if ( !isDefined( rocketAmmo ) ) { continue; } @@ -2138,15 +2190,15 @@ bot_target_vehicle_loop() } airborne_enemies = undefined; - - if(!isDefined(target)) + + if ( !isDefined( target ) ) { - if(isDefined(self getLockonAmmo())) + if ( isDefined( self getLockonAmmo() ) ) { - for(i = 0; i < level.bot_planes.size; i++) + for ( i = 0; i < level.bot_planes.size; i++ ) { enemy = level.bot_planes[i]; - + if ( !IsDefined( enemy ) ) { continue; @@ -2156,7 +2208,7 @@ bot_target_vehicle_loop() { continue; } - + if ( level.teamBased ) { if ( enemy.team == myteam ) @@ -2169,29 +2221,29 @@ bot_target_vehicle_loop() { continue; } - + if ( !BulletTracePassed( myEye, enemy.origin, false, enemy ) ) { continue; } - + target = enemy; break; } } } - - if(!isDefined(target)) + + if ( !isDefined( target ) ) { wait( RandomIntRange( 3, 5 ) ); return; } - - if(isDefined(target.bot_plane)) + + if ( isDefined( target.bot_plane ) ) { - self bot_plane_attack(target); - self freeze_player_controls(false); - self thread botStopMove(false); + self bot_plane_attack( target ); + self freeze_player_controls( false ); + self thread botStopMove( false ); } else { @@ -2210,11 +2262,11 @@ bot_target_vehicle() self endon( "disconnect" ); level endon ( "game_ended" ); - for (;;) + for ( ;; ) { wait( 1 ); - - if(isDefined(self GetThreat()) || self IsRemoteControlling() || self UseButtonPressed()) + + if ( isDefined( self GetThreat() ) || self IsRemoteControlling() || self UseButtonPressed() ) continue; self bot_target_vehicle_loop(); @@ -2229,7 +2281,7 @@ bot_use_equipment_think_loop() weapon = self.pers["bot"]["class_equipment"]; diff = self GetBotDiffNum(); - if (diff > 0) + if ( diff > 0 ) { if ( weapon == "camera_spike_mp" ) { @@ -2249,22 +2301,25 @@ bot_use_equipment_think_loop() } dir = self GetLookaheadDir(); + if ( !IsDefined( dir ) ) return; dir = VectorToAngles( dir ); + if ( abs( dir[1] - self.angles[1] ) > 5 ) return; dir = VectorNormalize( AnglesToForward( self.angles ) ); dir = vector_scale( dir, 32 ); goal = self.origin + dir; - - if (randomInt(100) > 35) + + if ( randomInt( 100 ) > 35 ) return; grenades = GetEntArray( "grenade", "classname" ); anyEquNear = false; + for ( i = 0; i < grenades.size; i++ ) { item = grenades[i]; @@ -2281,24 +2336,24 @@ bot_use_equipment_think_loop() grenades = undefined; - if (anyEquNear && diff > 0) + if ( anyEquNear && diff > 0 ) return; lastWeap = self getCurrentWeapon(); - self thread botStopMove(true); + self thread botStopMove( true ); - if (self ChangeToWeapon(weapon)) + if ( self ChangeToWeapon( weapon ) ) { self thread fire_current_weapon(); ret = self waittill_any_timeout( 5, "grenade_fire" ); - self notify("stop_firing_weapon"); + self notify( "stop_firing_weapon" ); - self thread changeToWeapon(lastWeap); + self thread changeToWeapon( lastWeap ); } - self thread botStopMove(false); + self thread botStopMove( false ); } /* @@ -2310,7 +2365,7 @@ bot_use_equipment_think() self endon( "disconnect" ); level endon ( "game_ended" ); - if(self.pers["bot"]["class_equipment"] == "" || self.pers["bot"]["class_equipment"] == "weapon_null_mp" || self.pers["bot"]["class_equipment"] == "satchel_charge_mp") + if ( self.pers["bot"]["class_equipment"] == "" || self.pers["bot"]["class_equipment"] == "weapon_null_mp" || self.pers["bot"]["class_equipment"] == "satchel_charge_mp" ) return; for ( ;; ) @@ -2320,16 +2375,16 @@ bot_use_equipment_think() if ( !self HasWeapon( self.pers["bot"]["class_equipment"] ) ) return; - if (!self GetAmmoCount(self.pers["bot"]["class_equipment"])) + if ( !self GetAmmoCount( self.pers["bot"]["class_equipment"] ) ) continue; - if ( self IsRemoteControlling()) + if ( self IsRemoteControlling() ) continue; - if ( isDefined(self getThreat()) ) + if ( isDefined( self getThreat() ) ) continue; - if (self._is_sprinting) + if ( self._is_sprinting ) continue; self bot_use_equipment_think_loop(); @@ -2339,33 +2394,33 @@ bot_use_equipment_think() /* Bots go to the revive */ -bot_go_revive(revive) +bot_go_revive( revive ) { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 1; - if (!isDefined(revive)) + if ( !isDefined( revive ) ) break; - if (!isDefined(revive.revivetrigger)) + if ( !isDefined( revive.revivetrigger ) ) break; - if (self isTouching(revive.revivetrigger)) + if ( self isTouching( revive.revivetrigger ) ) break; } - if(!isDefined(revive) || !isDefined(revive.revivetrigger)) - self notify("bad_path"); + if ( !isDefined( revive ) || !isDefined( revive.revivetrigger ) ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* @@ -2374,53 +2429,57 @@ bot_go_revive(revive) bot_revive_think_loop() { revivePlayer = undefined; - for(i = 0; i < level.players.size; i++) + + for ( i = 0; i < level.players.size; i++ ) { player = level.players[i]; - if(!isDefined(player.pers["team"])) - continue; - if(player == self) - continue; - if(self.pers["team"] != player.pers["team"]) - continue; - if(!isDefined(player.revivetrigger)) + if ( !isDefined( player.pers["team"] ) ) continue; - if (isDefined(player.currentlyBeingRevived) && player.currentlyBeingRevived) + if ( player == self ) continue; - if (!isDefined(player.revivetrigger.bots)) + if ( self.pers["team"] != player.pers["team"] ) + continue; + + if ( !isDefined( player.revivetrigger ) ) + continue; + + if ( isDefined( player.currentlyBeingRevived ) && player.currentlyBeingRevived ) + continue; + + if ( !isDefined( player.revivetrigger.bots ) ) player.revivetrigger.bots = 0; - if (player.revivetrigger.bots > 2) + if ( player.revivetrigger.bots > 2 ) continue; revivePlayer = player; } - if (!isDefined(revivePlayer)) + if ( !isDefined( revivePlayer ) ) return; self.bot_lock_goal = true; self SetBotGoal( revivePlayer.origin, 1 ); - self thread bot_inc_bots(revivePlayer.revivetrigger, true); - self thread bot_go_revive(revivePlayer); + self thread bot_inc_bots( revivePlayer.revivetrigger, true ); + self thread bot_go_revive( revivePlayer ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if(event != "goal" || !isDefined(revivePlayer) || (isDefined(revivePlayer.currentlyBeingRevived) && revivePlayer.currentlyBeingRevived) || !self isTouching(revivePlayer.revivetrigger) || self InLastStand()) + + if ( event != "goal" || !isDefined( revivePlayer ) || ( isDefined( revivePlayer.currentlyBeingRevived ) && revivePlayer.currentlyBeingRevived ) || !self isTouching( revivePlayer.revivetrigger ) || self InLastStand() ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - + reviveTime = GetDvarInt( #"revive_time_taken" ); self PressUseButton( reviveTime + 1 ); wait( reviveTime + 1.5 ); @@ -2436,11 +2495,11 @@ bot_revive_think() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); - + level endon( "game_ended" ); + if ( !level.teamBased ) return; - + for ( ;; ) { wait( randomintrange( 3, 5 ) ); @@ -2448,16 +2507,16 @@ bot_revive_think() if ( self HasScriptGoal() || self.bot_lock_goal ) continue; - if(self isDefusing() || self isPlanting()) + if ( self isDefusing() || self isPlanting() ) continue; - if (self inLastStand()) + if ( self inLastStand() ) continue; - if (self IsRemoteControlling()) + if ( self IsRemoteControlling() ) continue; - if(self UseButtonPressed()) + if ( self UseButtonPressed() ) continue; self bot_revive_think_loop(); @@ -2467,26 +2526,26 @@ bot_revive_think() /* Bot attacks dog */ -bot_dog_attack(dog) +bot_dog_attack( dog ) { - dog endon("death"); - + dog endon( "death" ); + wait_time = RandomIntRange( 7, 10 ); for ( i = 0; i < wait_time; i++ ) { wait( 1 ); - + if ( !IsDefined( dog ) ) { return; } - + if ( !IsAlive( dog ) ) { return; } - + if ( !BulletTracePassed( self.origin, dog.origin, false, dog ) ) { return; @@ -2523,18 +2582,18 @@ bot_dogs_think_loop() } } - if ( isDefined(dog.script_owner) && dog.script_owner == self ) + if ( isDefined( dog.script_owner ) && dog.script_owner == self ) { continue; } if ( DistanceSquared( self.origin, dog.origin ) < 1024 * 1024 ) { - if(!BulletTracePassed( self.origin, dog.origin, false, dog )) + if ( !BulletTracePassed( self.origin, dog.origin, false, dog ) ) continue; - + self SetScriptEnemy( dog ); - self bot_dog_attack(dog); + self bot_dog_attack( dog ); self ClearScriptEnemy(); break; } @@ -2559,8 +2618,8 @@ bot_dogs_think() if ( !IsDefined( level.dogs ) || level.dogs.size <= 0 ) level waittill( "called_in_the_dogs" ); - - if(isDefined(self GetThreat())) + + if ( isDefined( self GetThreat() ) ) continue; self bot_dogs_think_loop(); @@ -2570,7 +2629,7 @@ bot_dogs_think() /* Clears goal when events death */ -stop_go_target_on_death(tar) +stop_go_target_on_death( tar ) { self endon( "death" ); self endon( "disconnect" ); @@ -2578,7 +2637,7 @@ stop_go_target_on_death(tar) self endon( "bad_path" ); self endon( "goal" ); - tar waittill_either("death", "disconnect"); + tar waittill_either( "death", "disconnect" ); self ClearBotGoal(); } @@ -2590,19 +2649,20 @@ follow_target_loop() { threat = self GetThreat(); - if ( !isDefined(threat) ) + if ( !isDefined( threat ) ) return; - if (!isPlayer(threat)) + if ( !isPlayer( threat ) ) return; - if(randomInt(100) > 50) + if ( randomInt( 100 ) > 50 ) return; - self thread stop_go_target_on_death(threat); + self thread stop_go_target_on_death( threat ); - self SetBotGoal(threat.origin, 64); - if (self waittill_any_return("new_goal", "goal", "bad_path") != "new_goal") + self SetBotGoal( threat.origin, 64 ); + + if ( self waittill_any_return( "new_goal", "goal", "bad_path" ) != "new_goal" ) self ClearBotGoal(); } @@ -2613,14 +2673,14 @@ follow_target() { self endon( "death" ); self endon( "disconnect" ); - - for(;;) + + for ( ;; ) { wait 1; - + if ( self HasScriptGoal() || self.bot_lock_goal ) continue; - + self follow_target_loop(); } } @@ -2631,23 +2691,24 @@ follow_target() bot_watch_think_mw2_loop() { tube = self getValidTube(); - if (!isDefined(tube)) + + if ( !isDefined( tube ) ) { - if (self GetAmmoCount("m72_law_mp")) + if ( self GetAmmoCount( "m72_law_mp" ) ) tube = "m72_law_mp"; - else if (self GetAmmoCount("rpg_mp")) + else if ( self GetAmmoCount( "rpg_mp" ) ) tube = "rpg_mp"; else return; } - if (self GetCurrentWeapon() == tube) + if ( self GetCurrentWeapon() == tube ) return; - if (randomInt(100) > 35) + if ( randomInt( 100 ) > 35 ) return; - self thread ChangeToWeapon(tube); + self thread ChangeToWeapon( tube ); } /* @@ -2655,24 +2716,24 @@ bot_watch_think_mw2_loop() */ bot_watch_think_mw2() { - self endon("disconnect"); - self endon("death"); - level endon("game_ended"); + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); - for (;;) + for ( ;; ) { - wait randomIntRange(1, 4); - - if(self isDefusing() || self isPlanting()) + wait randomIntRange( 1, 4 ); + + if ( self isDefusing() || self isPlanting() ) continue; - if (self IsRemoteControlling()) + if ( self IsRemoteControlling() ) continue; - if (self InLastStand()) + if ( self InLastStand() ) continue; - if (isDefined(self GetThreat())) + if ( isDefined( self GetThreat() ) ) continue; self bot_watch_think_mw2_loop(); @@ -2683,57 +2744,58 @@ bot_watch_think_mw2() Fast swaps or reload cancels don't work cause t5 bots wait for the anim to complete Bots will think to switch weapons */ -bot_weapon_think_loop(data) +bot_weapon_think_loop( data ) { curWeap = self GetCurrentWeapon(); threat = self getThreat(); - if (isDefined(threat) && !isPlayer(threat)) + if ( isDefined( threat ) && !isPlayer( threat ) ) return; - - if (data.first) + + if ( data.first ) { data.first = false; - if (randomInt(100) > 10) + if ( randomInt( 100 ) > 10 ) return; } else { - if(curWeap != "none" && self getAmmoCount(curWeap) && curWeap != "strela_mp") + if ( curWeap != "none" && self getAmmoCount( curWeap ) && curWeap != "strela_mp" ) { - if(randomInt(100) > 2) + if ( randomInt( 100 ) > 2 ) return; - - if(isDefined(threat)) + + if ( isDefined( threat ) ) return; } } - + weaponslist = self getweaponslist(); weap = ""; - while(weaponslist.size) + + while ( weaponslist.size ) { - weapon = weaponslist[randomInt(weaponslist.size)]; - weaponslist = array_remove(weaponslist, weapon); - - if(!self getAmmoCount(weapon)) + weapon = weaponslist[randomInt( weaponslist.size )]; + weaponslist = array_remove( weaponslist, weapon ); + + if ( !self getAmmoCount( weapon ) ) continue; - - if (!maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) && !maps\mp\gametypes\_weapons::isSideArm( weapon ) && !isWeaponAltmode(weapon)) + + if ( !maps\mp\gametypes\_weapons::isPrimaryWeapon( weapon ) && !maps\mp\gametypes\_weapons::isSideArm( weapon ) && !isWeaponAltmode( weapon ) ) continue; - - if(curWeap == weapon || weapon == "none" || weapon == "" || weapon == "strela_mp") + + if ( curWeap == weapon || weapon == "none" || weapon == "" || weapon == "strela_mp" ) continue; - + weap = weapon; break; } - - if(weap == "") + + if ( weap == "" ) return; - - self thread changeToWeapon(weap); + + self thread changeToWeapon( weap ); } /* @@ -2742,170 +2804,173 @@ bot_weapon_think_loop(data) */ bot_weapon_think() { - self endon("death"); - self endon("disconnect"); - level endon("game_ended"); + self endon( "death" ); + self endon( "disconnect" ); + level endon( "game_ended" ); data = spawnStruct(); data.first = true; - - for(;;) + + for ( ;; ) { - self waittill_any_timeout(randomIntRange(2, 4), "bot_force_check_switch"); - - if(self isDefusing() || self isPlanting()) + self waittill_any_timeout( randomIntRange( 2, 4 ), "bot_force_check_switch" ); + + if ( self isDefusing() || self isPlanting() ) continue; - if (self IsRemoteControlling()) + if ( self IsRemoteControlling() ) continue; - if (self InLastStand()) + if ( self InLastStand() ) continue; - self bot_weapon_think_loop(data); + self bot_weapon_think_loop( data ); } } /* Bots pay attention to the uav */ -bot_uav_think_loop(data) +bot_uav_think_loop( data ) { - myTeam = self.pers[ "team" ]; + myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); diff = self GetBotDiffNum(); - - hasCam = isDefined(self.cameraSpike); - - if(self.bot_scrambled && !hasCam) + + hasCam = isDefined( self.cameraSpike ); + + if ( self.bot_scrambled && !hasCam ) return; - + players = get_players(); - + hasUAV = false; hasSR = false; - if(level.teamBased) + + if ( level.teamBased ) { - if(level.activeCounterUAVs[otherTeam] && !hasCam) + if ( level.activeCounterUAVs[otherTeam] && !hasCam ) return; - + hasSR = level.activeSatellites[myTeam]; hasUAV = level.activeUAVs[myTeam]; } else { shouldContinue = false; - - for (i = 0; i < players.size; i++) + + for ( i = 0; i < players.size; i++ ) { player = players[i]; - - if(player == self) + + if ( player == self ) continue; - - if(!isDefined(player.team)) + + if ( !isDefined( player.team ) ) continue; - - if(isDefined(level.activeCounterUAVs[player.entnum]) && level.activeCounterUAVs[player.entnum]) + + if ( isDefined( level.activeCounterUAVs[player.entnum] ) && level.activeCounterUAVs[player.entnum] ) continue; - + shouldContinue = true; break; } - - if(shouldContinue && !hasCam) + + if ( shouldContinue && !hasCam ) return; - + hasSR = level.activeSatellites[self.entnum]; hasUAV = level.activeUAVs[self.entnum]; } - - if(level.hardcoreMode && !hasUAV && !hasSR && !hasCam) + + if ( level.hardcoreMode && !hasUAV && !hasSR && !hasCam ) return; - + dist = GetDvarInt( #"scr_help_dist" ); dist = dist * dist * 8; - - if(!data.wasFooled && level.bot_decoys.size && !hasCam) + + if ( !data.wasFooled && level.bot_decoys.size && !hasCam ) { shouldContinue = false; - - for(i = 0; i < level.bot_decoys.size; i++) + + for ( i = 0; i < level.bot_decoys.size; i++ ) { g = level.bot_decoys[i]; - - if(isDefined(g.owner) && g.owner == self) + + if ( isDefined( g.owner ) && g.owner == self ) continue; - - if(level.teamBased && g.team == myTeam) + + if ( level.teamBased && g.team == myTeam ) continue; - - if(DistanceSquared(self.origin, g.origin) > dist) + + if ( DistanceSquared( self.origin, g.origin ) > dist ) continue; - - if(lengthsquared( g getVelocity() ) > 10000) + + if ( lengthsquared( g getVelocity() ) > 10000 ) continue; - - if(diff > 0) + + if ( diff > 0 ) data.wasFooled = true; - + self SetBotGoal( g.origin, 128 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + shouldContinue = true; break; } - - if(shouldContinue) + + if ( shouldContinue ) return; } - + if ( diff <= 0 ) { return; } - - for (i = 0; i < players.size; i++) + + for ( i = 0; i < players.size; i++ ) { player = players[i]; - - if(player == self) + + if ( player == self ) continue; - - if(level.teambased && player.team == myTeam) + + if ( level.teambased && player.team == myTeam ) continue; - - if(!isAlive(player)) + + if ( !isAlive( player ) ) continue; - - if(player.sessionstate != "playing") + + if ( player.sessionstate != "playing" ) continue; - - if(DistanceSquared(self.origin, player.origin) > dist) + + if ( DistanceSquared( self.origin, player.origin ) > dist ) continue; - - if(hasCam) + + if ( hasCam ) { - if(!self.cameraSpike maps\mp\gametypes\_weaponobjects::isStunned()) + if ( !self.cameraSpike maps\mp\gametypes\_weaponobjects::isStunned() ) { - if ( VectorDot( VectorNormalize( AnglesToForward( self.cameraSpike.cameraHead.angles ) ), VectorNormalize( player.origin - self.cameraSpike.origin ) ) >= 0.342 && SightTracePassed(player.origin+(0,0,5), self.cameraSpike.origin+(0,0,5), false, self.cameraSpike) && !player hasPerk("specialty_nottargetedbyai")) // cos 70 degrees + if ( VectorDot( VectorNormalize( AnglesToForward( self.cameraSpike.cameraHead.angles ) ), VectorNormalize( player.origin - self.cameraSpike.origin ) ) >= 0.342 && SightTracePassed( player.origin + ( 0, 0, 5 ), self.cameraSpike.origin + ( 0, 0, 5 ), false, self.cameraSpike ) && !player hasPerk( "specialty_nottargetedbyai" ) ) // cos 70 degrees { self SetBotGoal( player.origin, 128 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + break; } } } - else if(hasSR || (!isSubStr(player getCurrentWeapon(), "_silencer_") && player.bot_firing) || (hasUAV && !player hasPerk("specialty_gpsjammer")) || (isDefined(self.acousticSensor) && !self.acousticSensor maps\mp\gametypes\_weaponobjects::isStunned() && !player hasPerk("specialty_nomotionsensor") && distance2d(self.acousticSensor.origin, player.origin) < 666)) + else if ( hasSR || ( !isSubStr( player getCurrentWeapon(), "_silencer_" ) && player.bot_firing ) || ( hasUAV && !player hasPerk( "specialty_gpsjammer" ) ) || ( isDefined( self.acousticSensor ) && !self.acousticSensor maps\mp\gametypes\_weaponobjects::isStunned() && !player hasPerk( "specialty_nomotionsensor" ) && distance2d( self.acousticSensor.origin, player.origin ) < 666 ) ) { self SetBotGoal( player.origin, 128 ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + break; } } @@ -2918,23 +2983,24 @@ bot_uav_think() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); - + level endon( "game_ended" ); + data = spawnStruct(); data.wasFooled = false; - for(;;) + + for ( ;; ) { wait 0.75; - + if ( self HasScriptGoal() ) continue; - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { continue; } - self bot_uav_think_loop(data); + self bot_uav_think_loop( data ); } } @@ -2946,32 +3012,32 @@ bot_revenge_think() self endon( "death" ); self endon( "disconnect" ); - if (isDefined(self.lastKiller) && isAlive(self.lastKiller)) + if ( isDefined( self.lastKiller ) && isAlive( self.lastKiller ) ) { - if(bulletTracePassed(self getEye(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller)) + if ( bulletTracePassed( self getEye(), self.lastKiller getTagOrigin( "j_spineupper" ), false, self.lastKiller ) ) { - self setAttacker(self.lastKiller); + self setAttacker( self.lastKiller ); } } - - if(!isDefined(self.killerLocation)) + + if ( !isDefined( self.killerLocation ) ) return; loc = self.killerLocation; - for(;;) + for ( ;; ) { wait( RandomIntRange( 1, 5 ) ); - - if(self HasScriptGoal() || self.bot_lock_goal) + + if ( self HasScriptGoal() || self.bot_lock_goal ) return; - + if ( randomint( 100 ) < 75 ) return; - + self SetBotGoal( loc, 64 ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } } @@ -2982,57 +3048,61 @@ bot_revenge_think() bot_listen_to_steps_loop() { dist = 100; - if(self hasPerk("specialty_loudenemies")) + + if ( self hasPerk( "specialty_loudenemies" ) ) dist *= 1.4; - + dist *= dist; - + heard = undefined; - for(i = level.players.size-1 ; i >= 0; i--) + + for ( i = level.players.size - 1 ; i >= 0; i-- ) { player = level.players[i]; - if(player == self) + if ( player == self ) continue; - if (!isDefined(player.team)) + if ( !isDefined( player.team ) ) continue; - if(level.teamBased && self.team == player.team) - continue; - if(player.sessionstate != "playing") - continue; - if(!isAlive(player)) + if ( level.teamBased && self.team == player.team ) continue; - if( lengthsquared( player getVelocity() ) < 20000 ) + if ( player.sessionstate != "playing" ) continue; - - if( distanceSquared(player.origin, self.origin) > dist ) + + if ( !isAlive( player ) ) continue; - - if( player hasPerk("specialty_quieter")) + + if ( lengthsquared( player getVelocity() ) < 20000 ) continue; - + + if ( distanceSquared( player.origin, self.origin ) > dist ) + continue; + + if ( player hasPerk( "specialty_quieter" ) ) + continue; + heard = player; break; } - - if(!IsDefined(heard)) + + if ( !IsDefined( heard ) ) return; - - if(bulletTracePassed(self getEye(), heard getTagOrigin( "j_spineupper" ), false, heard)) + + if ( bulletTracePassed( self getEye(), heard getTagOrigin( "j_spineupper" ), false, heard ) ) { - self setAttacker(heard); + self setAttacker( heard ); return; } - - if (self HasScriptGoal() || self.bot_lock_goal) + + if ( self HasScriptGoal() || self.bot_lock_goal ) return; - + self SetBotGoal( heard.origin, 64 ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } @@ -3041,13 +3111,13 @@ bot_listen_to_steps_loop() */ bot_listen_to_steps() { - self endon("disconnect"); - self endon("death"); - - for(;;) + self endon( "disconnect" ); + self endon( "death" ); + + for ( ;; ) { wait 1; - + self bot_listen_to_steps_loop(); } } @@ -3066,20 +3136,20 @@ bot_radiation_think_loop() if ( DistanceSquared( self.origin, origin ) < 512 * 512 ) { self SetBotGoal( origin, 32 ); - + event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if(event != "goal") + + if ( event != "goal" ) return; - + self SetBotGoal( self.origin, 32 ); - + self PressUseButton( 3 ); wait( 3 ); - + self ClearBotGoal(); } @@ -3104,14 +3174,14 @@ bot_radiation_think() for ( ;; ) { wait( RandomIntRange( 8, 15 ) ); - + if ( self HasScriptGoal() ) continue; - + if ( self IsRemoteControlling() || self.bot_lock_goal ) continue; - if (self UseButtonPressed()) + if ( self UseButtonPressed() ) continue; self bot_radiation_think_loop(); @@ -3123,7 +3193,7 @@ bot_radiation_think() */ bot_dom_spawn_kill_think_loop() { - myTeam = self.pers[ "team" ]; + myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam ); @@ -3131,11 +3201,12 @@ bot_dom_spawn_kill_think_loop() return; otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); - - if (myFlagCount <= otherFlagCount || otherFlagCount != 1) + + 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 ) @@ -3143,18 +3214,18 @@ bot_dom_spawn_kill_think_loop() flag = level.flags[i]; } - - if(!isDefined(flag)) + + if ( !isDefined( flag ) ) return; - - if(DistanceSquared(self.origin, flag.origin) < 2048*2048) + + if ( DistanceSquared( self.origin, flag.origin ) < 2048 * 2048 ) return; self SetBotGoal( flag.origin, 1024 ); - - self thread bot_dom_watch_flags(myFlagCount, myTeam); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_dom_watch_flags( myFlagCount, myTeam ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } @@ -3172,13 +3243,13 @@ bot_dom_spawn_kill_think() for ( ;; ) { wait( randomintrange( 10, 20 ) ); - + if ( randomint( 100 ) < 20 ) continue; - - if ( self HasScriptGoal() || self.bot_lock_goal) + + if ( self HasScriptGoal() || self.bot_lock_goal ) continue; - + self bot_dom_spawn_kill_think_loop(); } } @@ -3186,7 +3257,7 @@ bot_dom_spawn_kill_think() /* Calls 'bad_path' when the flag count changes */ -bot_dom_watch_flags(count, myTeam) +bot_dom_watch_flags( count, myTeam ) { self endon( "death" ); self endon( "disconnect" ); @@ -3194,15 +3265,15 @@ bot_dom_watch_flags(count, myTeam) self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 0.5; - if (maps\mp\gametypes\dom::getTeamFlagCount( myTeam ) != count) + if ( maps\mp\gametypes\dom::getTeamFlagCount( myTeam ) != count ) break; } - - self notify("bad_path"); + + self notify( "bad_path" ); } /* @@ -3212,27 +3283,28 @@ bot_dom_def_think_loop() { myTeam = self.pers[ "team" ]; flag = undefined; + 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) ) + + if ( !isDefined( flag ) || DistanceSquared( self.origin, level.flags[i].origin ) < DistanceSquared( self.origin, flag.origin ) ) flag = level.flags[i]; } - - if ( !isDefined(flag) ) + + if ( !isDefined( flag ) ) return; self SetBotGoal( flag.origin, 128 ); - - self thread bot_dom_watch_for_flashing(flag, myTeam); - self thread bots_watch_touch_obj(flag); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_dom_watch_for_flashing( flag, myTeam ); + self thread bots_watch_touch_obj( flag ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } @@ -3250,10 +3322,10 @@ bot_dom_def_think() for ( ;; ) { wait( randomintrange( 1, 3 ) ); - + if ( randomint( 100 ) < 35 ) continue; - + if ( self HasScriptGoal() || self.bot_lock_goal ) continue; @@ -3264,26 +3336,26 @@ bot_dom_def_think() /* Watches while the flag is under capture */ -bot_dom_watch_for_flashing(flag, myTeam) +bot_dom_watch_for_flashing( flag, myTeam ) { self endon( "death" ); self endon( "disconnect" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - - for (;;) + + for ( ;; ) { wait 0.5; - if (!isDefined(flag)) + if ( !isDefined( flag ) ) break; - if (flag maps\mp\gametypes\dom::getFlagTeam() != myTeam || !flag.useObj.objPoints[myTeam].isFlashing) + if ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam || !flag.useObj.objPoints[myTeam].isFlashing ) break; } - - self notify("bad_path"); + + self notify( "bad_path" ); } /* @@ -3291,7 +3363,7 @@ bot_dom_watch_for_flashing(flag, myTeam) */ bot_dom_cap_think_loop() { - myTeam = self.pers[ "team" ]; + myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); myFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( myTeam ); @@ -3301,7 +3373,7 @@ bot_dom_cap_think_loop() otherFlagCount = maps\mp\gametypes\dom::getTeamFlagCount( otherTeam ); - if (game["teamScores"][myteam] >= game["teamScores"][otherTeam]) + if ( game["teamScores"][myteam] >= game["teamScores"][otherTeam] ) { if ( myFlagCount < otherFlagCount ) { @@ -3311,7 +3383,7 @@ bot_dom_cap_think_loop() else if ( myFlagCount == otherFlagCount ) { if ( randomint( 100 ) < 35 ) - return; + return; } else if ( myFlagCount > otherFlagCount ) { @@ -3322,6 +3394,7 @@ bot_dom_cap_think_loop() flag = undefined; flags = []; + for ( i = 0; i < level.flags.size; i++ ) { if ( level.flags[i] maps\mp\gametypes\dom::getFlagTeam() == myTeam ) @@ -3330,51 +3403,51 @@ bot_dom_cap_think_loop() flags[flags.size] = level.flags[i]; } - if (randomInt(100) > 30) + if ( randomInt( 100 ) > 30 ) { for ( i = 0; i < flags.size; i++ ) { - if ( !isDefined(flag) || DistanceSquared(self.origin,level.flags[i].origin) < DistanceSquared(self.origin,flag.origin) ) + if ( !isDefined( flag ) || DistanceSquared( self.origin, level.flags[i].origin ) < DistanceSquared( self.origin, flag.origin ) ) flag = level.flags[i]; } } - else if (flags.size) + else if ( flags.size ) { - flag = PickRandom(flags); + flag = PickRandom( flags ); } - if ( !isDefined(flag) ) + if ( !isDefined( flag ) ) return; - + self.bot_lock_goal = true; self SetBotGoal( flag.origin, 64 ); - - self thread bot_dom_go_cap_flag(flag, myteam); + + self thread bot_dom_go_cap_flag( flag, myteam ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - - if (event != "new_goal") + + if ( event != "new_goal" ) self ClearBotGoal(); - if (event != "goal") + if ( event != "goal" ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - while ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam && self isTouching(flag) ) + while ( flag maps\mp\gametypes\dom::getFlagTeam() != myTeam && self isTouching( flag ) ) { cur = flag.useObj.curProgress; wait 0.5; - - if(flag.useObj.curProgress == cur) + + if ( flag.useObj.curProgress == cur ) break;//some enemy is near us, kill him } self ClearBotGoal(); - + self.bot_lock_goal = false; } @@ -3385,20 +3458,20 @@ bot_dom_cap_think() { self endon( "death" ); self endon( "disconnect" ); - + if ( level.gametype != "dom" ) return; for ( ;; ) { wait( randomintrange( 3, 12 ) ); - + if ( self.bot_lock_goal ) { continue; } - if ( !isDefined(level.flags) || level.flags.size == 0 ) + if ( !isDefined( level.flags ) || level.flags.size == 0 ) continue; self bot_dom_cap_think_loop(); @@ -3408,32 +3481,32 @@ bot_dom_cap_think() /* Bot goes to the flag, watching while they don't have the flag */ -bot_dom_go_cap_flag(flag, myteam) +bot_dom_go_cap_flag( flag, myteam ) { self endon( "death" ); self endon( "disconnect" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - - for (;;) + + for ( ;; ) { - wait randomintrange(2,4); + wait randomintrange( 2, 4 ); - if (!isDefined(flag)) + if ( !isDefined( flag ) ) break; - if (flag maps\mp\gametypes\dom::getFlagTeam() == myTeam) + if ( flag maps\mp\gametypes\dom::getFlagTeam() == myTeam ) break; - if (self isTouching(flag)) + if ( self isTouching( flag ) ) break; } - - if (flag maps\mp\gametypes\dom::getFlagTeam() == myTeam) - self notify("bad_path"); + + if ( flag maps\mp\gametypes\dom::getFlagTeam() == myTeam ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* @@ -3443,90 +3516,91 @@ bot_hq_loop() { myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + radio = level.radio; gameobj = radio.gameobject; - origin = ( radio.origin[0], radio.origin[1], radio.origin[2]+5 ); - + origin = ( radio.origin[0], radio.origin[1], radio.origin[2] + 5 ); + //if neut or enemy - if(gameobj.ownerTeam != myTeam) + if ( gameobj.ownerTeam != myTeam ) { - if(gameobj.interactTeam == "none")//wait for it to become active + if ( gameobj.interactTeam == "none" ) //wait for it to become active { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - + //capture it - + self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - self thread bot_hq_go_cap(gameobj, radio); + self thread bot_hq_go_cap( gameobj, radio ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if (event != "goal") + + if ( event != "goal" ) { self.bot_lock_goal = false; return; } - - if(!self isTouching(gameobj.trigger) || level.radio != radio) + + if ( !self isTouching( gameobj.trigger ) || level.radio != radio ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - while(self isTouching(gameobj.trigger) && gameobj.ownerTeam != myTeam && level.radio == radio) + + while ( self isTouching( gameobj.trigger ) && gameobj.ownerTeam != myTeam && level.radio == radio ) { cur = gameobj.curProgress; wait 0.5; - - if(cur == gameobj.curProgress) + + if ( cur == gameobj.curProgress ) break;//no prog made, enemy must be capping } - + self ClearBotGoal(); self.bot_lock_goal = false; } else//we own it { - if(gameobj.objPoints[myteam].isFlashing)//underattack + if ( gameobj.objPoints[myteam].isFlashing ) //underattack { self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - self thread bot_hq_watch_flashing(gameobj, radio); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_hq_watch_flashing( gameobj, radio ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); self.bot_lock_goal = false; return; } - - if(self HasScriptGoal()) + + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } } @@ -3545,16 +3619,16 @@ bot_hq() for ( ;; ) { wait( randomintrange( 3, 5 ) ); - + if ( self.bot_lock_goal ) { continue; } - - if(!isDefined(level.radio)) + + if ( !isDefined( level.radio ) ) continue; - - if(!isDefined(level.radio.gameobject)) + + if ( !isDefined( level.radio.gameobject ) ) continue; self bot_hq_loop(); @@ -3564,7 +3638,7 @@ bot_hq() /* Waits until not touching the trigger and it is the current radio. */ -bot_hq_go_cap(obj, radio) +bot_hq_go_cap( obj, radio ) { self endon( "death" ); self endon( "disconnect" ); @@ -3572,54 +3646,54 @@ bot_hq_go_cap(obj, radio) self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { - wait randomintrange(2,4); + wait randomintrange( 2, 4 ); - if (!isDefined(obj)) + if ( !isDefined( obj ) ) break; - if (self isTouching(obj.trigger)) + if ( self isTouching( obj.trigger ) ) break; - if (level.radio != radio) + if ( level.radio != radio ) break; } - - if(level.radio != radio) - self notify("bad_path"); + + if ( level.radio != radio ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* Waits while the radio is under attack. */ -bot_hq_watch_flashing(obj, radio) +bot_hq_watch_flashing( obj, radio ) { self endon( "death" ); self endon( "disconnect" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - + myteam = self.team; - for (;;) + for ( ;; ) { wait 0.5; - if (!isDefined(obj)) + if ( !isDefined( obj ) ) break; - if (!obj.objPoints[myteam].isFlashing) + if ( !obj.objPoints[myteam].isFlashing ) break; - if (level.radio != radio) + if ( level.radio != radio ) break; } - - self notify("bad_path"); + + self notify( "bad_path" ); } /* @@ -3629,181 +3703,188 @@ bot_sab_loop() { myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + bomb = level.sabBomb; bombteam = bomb.ownerTeam; carrier = bomb.carrier; - timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining()/1000; - + timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining() / 1000; + // the bomb is ours, we are on the offence - if(bombteam == myTeam) + if ( bombteam == myTeam ) { site = level.bombZones[otherTeam]; - origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+32 ); - + origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 32 ); + // protect our planted bomb - if(level.bombPlanted) + if ( level.bombPlanted ) { // kill defuser - if(site isInUse()) //somebody is defusing our bomb we planted + if ( site isInUse() ) //somebody is defusing our bomb we planted { self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - self thread bot_defend_site(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_defend_site( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + self.bot_lock_goal = false; return; } - + //else hang around the site - if(DistanceSquared(origin, self.origin) <= 1024*1024) + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( origin, 256 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + self.bot_lock_goal = false; return; } - + // we are not the carrier - if(!self isBombCarrier()) + if ( !self isBombCarrier() ) { // lets escort the bomb carrier - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - + origin = carrier.origin; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - self thread bot_escort_obj(bomb, carrier); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_escort_obj( bomb, carrier ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } // we are the carrier of the bomb, lets check if we need to plant - timepassed = maps\mp\gametypes\_globallogic_utils::getTimePassed()/1000; - - if(timepassed < 120 && timeleft >= 90 && randomInt(100) < 98) + timepassed = maps\mp\gametypes\_globallogic_utils::getTimePassed() / 1000; + + if ( timepassed < 120 && timeleft >= 90 && randomInt( 100 ) < 98 ) return; - + self.bot_lock_goal = true; self SetBotGoal( origin, 1 ); - self thread bot_go_plant(site); + self thread bot_go_plant( site ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - if(event != "goal" || level.bombPlanted || !self isTouching(site.trigger) || site IsInUse() || self inLastStand() || isDefined(self getThreat())) + if ( event != "goal" || level.bombPlanted || !self isTouching( site.trigger ) || site IsInUse() || self inLastStand() || isDefined( self getThreat() ) ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - self bot_use_bomb_thread(site); + + self bot_use_bomb_thread( site ); wait 1; - + self ClearBotGoal(); self.bot_lock_goal = false; } - else if(bombteam == otherTeam) // the bomb is theirs, we are on the defense + else if ( bombteam == otherTeam ) // the bomb is theirs, we are on the defense { site = level.bombZones[myteam]; - - if(!isDefined(site.bots)) + + if ( !isDefined( site.bots ) ) site.bots = 0; - + // protect our site from planters - if(!level.bombPlanted) + if ( !level.bombPlanted ) { //kill bomb carrier - if(site.bots > 2 || randomInt(100) < 45) + if ( site.bots > 2 || randomInt( 100 ) < 45 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(carrier hasPerk( "specialty_gpsjammer" )) + + if ( carrier hasPerk( "specialty_gpsjammer" ) ) return; - + origin = carrier.origin; - + self SetBotGoal( origin, 64 ); - self thread bot_escort_obj(bomb, carrier); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_escort_obj( bomb, carrier ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - + //protect bomb site - origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+32 ); - - self thread bot_inc_bots(site); - - if(site isInUse())//somebody is planting + origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 32 ); + + self thread bot_inc_bots( site ); + + if ( site isInUse() ) //somebody is planting { self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - self thread bot_inc_bots(site); - - self thread bot_defend_site(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_inc_bots( site ); + + self thread bot_defend_site( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else hang around the site - if(DistanceSquared(origin, self.origin) <= 1024*1024) + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) { wait 4; - self notify("bot_inc_bots"); site.bots--; + self notify( "bot_inc_bots" ); + site.bots--; return; } - + self.bot_lock_goal = true; self SetBotGoal( origin, 256 ); - self thread bot_inc_bots(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_inc_bots( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + self.bot_lock_goal = false; return; } - + // bomb is planted we need to defuse - origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+32 ); - + origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 32 ); + // someone else is defusing, lets just hang around - if(site.bots > 1) + if ( site.bots > 1 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - self thread bot_go_defuse(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_go_defuse( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } @@ -3811,40 +3892,40 @@ bot_sab_loop() self.bot_lock_goal = true; self SetBotGoal( origin, 1 ); - self thread bot_inc_bots(site); - self thread bot_go_defuse(site); + self thread bot_inc_bots( site ); + self thread bot_go_defuse( site ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - if(event != "goal" || !level.bombPlanted || site IsInUse() || !self isTouching(site.trigger) || self InLastStand() || isDefined(self getThreat())) + if ( event != "goal" || !level.bombPlanted || site IsInUse() || !self isTouching( site.trigger ) || self InLastStand() || isDefined( self getThreat() ) ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - self bot_use_bomb_thread(site); + + self bot_use_bomb_thread( site ); wait 1; self ClearBotGoal(); - + self.bot_lock_goal = false; } else // we need to go get the bomb! { - origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2]+32 ); - + origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 32 ); + self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - - self thread bot_get_obj(bomb); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_get_obj( bomb ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } @@ -3857,7 +3938,7 @@ bot_sab() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); if ( level.gametype != "sab" ) return; @@ -3865,19 +3946,19 @@ bot_sab() for ( ;; ) { wait( randomintrange( 3, 5 ) ); - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { continue; } - - if(!isDefined(level.sabBomb)) - continue; - - if(!isDefined(level.bombZones) || !level.bombZones.size) + + if ( !isDefined( level.sabBomb ) ) continue; - if (self IsPlanting() || self isDefusing()) + if ( !isDefined( level.bombZones ) || !level.bombZones.size ) + continue; + + if ( self IsPlanting() || self isDefusing() ) continue; self bot_sab_loop(); @@ -3887,145 +3968,148 @@ bot_sab() /* Bots play sd defenders */ -bot_sd_defenders_loop(data) +bot_sd_defenders_loop( data ) { myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + // bomb not planted, lets protect our sites - if(!level.bombPlanted) + if ( !level.bombPlanted ) { - timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining()/1000; - - if(timeleft >= 90) + timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining() / 1000; + + if ( timeleft >= 90 ) return; - + // check for a bomb carrier, and camp the bomb - if(!level.multiBomb && isDefined(level.sdBomb)) + if ( !level.multiBomb && isDefined( level.sdBomb ) ) { bomb = level.sdBomb; carrier = level.sdBomb.carrier; - - if(!isDefined(carrier)) + + if ( !isDefined( carrier ) ) { - origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2]+32 ); - + origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 32 ); + //hang around the bomb - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - self thread bot_get_obj(bomb); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_get_obj( bomb ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } } - + // pick a site to protect - if(!isDefined(level.bombZones) || !level.bombZones.size) + if ( !isDefined( level.bombZones ) || !level.bombZones.size ) return; - + sites = []; - for(i = 0; i < level.bombZones.size; i++) + + for ( i = 0; i < level.bombZones.size; i++ ) { sites[sites.size] = level.bombZones[i]; } - - if(!sites.size) + + if ( !sites.size ) return; - - if (data.rand > 50) - site = self bot_array_nearest_curorigin(sites); + + if ( data.rand > 50 ) + site = self bot_array_nearest_curorigin( sites ); else - site = PickRandom(sites); - - if(!isDefined(site)) + site = PickRandom( sites ); + + if ( !isDefined( site ) ) return; - - origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+32 ); - - if(site isInUse())//somebody is planting + + origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 32 ); + + if ( site isInUse() ) //somebody is planting { self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - self thread bot_defend_site(site); + self thread bot_defend_site( site ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else hang around the site - if(DistanceSquared(origin, self.origin) <= 1024*1024) + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( origin, 256 ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + // bomb is planted, we need to defuse - if(!isDefined(level.defuseObject)) + if ( !isDefined( level.defuseObject ) ) return; - + defuse = level.defuseObject; - - if(!isDefined(defuse.bots)) + + if ( !isDefined( defuse.bots ) ) defuse.bots = 0; - - origin = ( defuse.curorigin[0], defuse.curorigin[1], defuse.curorigin[2]+32 ); - + + origin = ( defuse.curorigin[0], defuse.curorigin[1], defuse.curorigin[2] + 32 ); + // someone is going to go defuse ,lets just hang around - if(defuse.bots > 1) + if ( defuse.bots > 1 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - self thread bot_go_defuse(defuse); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_go_defuse( defuse ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } // lets defuse self.bot_lock_goal = true; self SetBotGoal( origin, 1 ); - self thread bot_inc_bots(defuse); - self thread bot_go_defuse(defuse); + self thread bot_inc_bots( defuse ); + self thread bot_go_defuse( defuse ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if(event != "goal" || !level.bombPlanted || defuse isInUse() || !self isTouching(defuse.trigger) || self InLastStand() || isDefined(self getThreat())) + + if ( event != "goal" || !level.bombPlanted || defuse isInUse() || !self isTouching( defuse.trigger ) || self InLastStand() || isDefined( self getThreat() ) ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - self bot_use_bomb_thread(defuse); + + self bot_use_bomb_thread( defuse ); wait 1; self ClearBotGoal(); self.bot_lock_goal = false; @@ -4038,43 +4122,43 @@ bot_sd_defenders() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); if ( level.gametype != "sd" ) return; - - if(self.team == game["attackers"]) + + if ( self.team == game["attackers"] ) return; data = spawnStruct(); - data.rand = randomInt(100); + data.rand = randomInt( 100 ); for ( ;; ) { wait( randomintrange( 3, 5 ) ); - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { continue; } - if (self IsPlanting() || self isDefusing()) + if ( self IsPlanting() || self isDefusing() ) continue; - self bot_sd_defenders_loop(data); + self bot_sd_defenders_loop( data ); } } /* Bots play sd attackers */ -bot_sd_attackers_loop(data) +bot_sd_attackers_loop( data ) { - if(data.first) + if ( data.first ) data.first = false; else wait( randomintrange( 3, 5 ) ); - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { return; @@ -4082,160 +4166,163 @@ bot_sd_attackers_loop(data) myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + //bomb planted - if(level.bombPlanted) + if ( level.bombPlanted ) { - if(!isDefined(level.defuseObject)) + if ( !isDefined( level.defuseObject ) ) return; - + site = level.defuseObject; - - origin = ( site.curorigin[0], site.curorigin[1], site.curorigin[2]+32 ); - - if(site IsInUse())//somebody is defusing + + origin = ( site.curorigin[0], site.curorigin[1], site.curorigin[2] + 32 ); + + if ( site IsInUse() ) //somebody is defusing { self.bot_lock_goal = true; - + self SetBotGoal( origin, 64 ); - - self thread bot_defend_site(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + self thread bot_defend_site( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else hang around the site - if(DistanceSquared(origin, self.origin) <= 1024*1024) + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( origin, 256 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - - timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining()/1000; - timepassed = maps\mp\gametypes\_globallogic_utils::getTimePassed()/1000; - + + timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining() / 1000; + timepassed = maps\mp\gametypes\_globallogic_utils::getTimePassed() / 1000; + //dont have a bomb - if(!self IsBombCarrier() && !level.multiBomb) + if ( !self IsBombCarrier() && !level.multiBomb ) { - if(!isDefined(level.sdBomb)) + if ( !isDefined( level.sdBomb ) ) return; - + bomb = level.sdBomb; carrier = level.sdBomb.carrier; - + //bomb is picked up - if(isDefined(carrier)) + if ( isDefined( carrier ) ) { //escort the bomb carrier - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - + origin = carrier.origin; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - self thread bot_escort_obj(bomb, carrier); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_escort_obj( bomb, carrier ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - - if(!isDefined(bomb.bots)) + + if ( !isDefined( bomb.bots ) ) bomb.bots = 0; - - origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2]+32 ); - + + origin = ( bomb.curorigin[0], bomb.curorigin[1], bomb.curorigin[2] + 32 ); + //hang around the bomb if other is going to go get it - if(bomb.bots > 1) + if ( bomb.bots > 1 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - - self thread bot_get_obj(bomb); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + self thread bot_get_obj( bomb ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } // go get the bomb self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - self thread bot_inc_bots(bomb); - self thread bot_get_obj(bomb); + self thread bot_inc_bots( bomb ); + self thread bot_get_obj( bomb ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); self.bot_lock_goal = false; return; } - + // check if to plant - if(timepassed < 120 && timeleft >= 90 && randomInt(100) < 98) + if ( timepassed < 120 && timeleft >= 90 && randomInt( 100 ) < 98 ) return; - - if(!isDefined(level.bombZones) || !level.bombZones.size) + + if ( !isDefined( level.bombZones ) || !level.bombZones.size ) return; - + sites = []; - for(i = 0; i < level.bombZones.size; i++) + + for ( i = 0; i < level.bombZones.size; i++ ) { sites[sites.size] = level.bombZones[i]; } - - if(!sites.size) + + if ( !sites.size ) return; - - if(data.rand > 50) - plant = self bot_array_nearest_curorigin(sites); + + if ( data.rand > 50 ) + plant = self bot_array_nearest_curorigin( sites ); else - plant = PickRandom(sites); - - if(!isDefined(plant)) + plant = PickRandom( sites ); + + if ( !isDefined( plant ) ) return; - - origin = ( plant.curorigin[0]+50, plant.curorigin[1]+50, plant.curorigin[2]+32 ); - + + origin = ( plant.curorigin[0] + 50, plant.curorigin[1] + 50, plant.curorigin[2] + 32 ); + self.bot_lock_goal = true; self SetBotGoal( origin, 1 ); - self thread bot_go_plant(plant); + self thread bot_go_plant( plant ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if(event != "goal" || level.bombPlanted || plant.visibleTeam == "none" || !self isTouching(plant.trigger) || self InLastStand() || isDefined(self getThreat()) || plant IsInUse()) + + if ( event != "goal" || level.bombPlanted || plant.visibleTeam == "none" || !self isTouching( plant.trigger ) || self InLastStand() || isDefined( self getThreat() ) || plant IsInUse() ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - self bot_use_bomb_thread(plant); + + self bot_use_bomb_thread( plant ); wait 1; - + self ClearBotGoal(); self.bot_lock_goal = false; } @@ -4247,21 +4334,21 @@ bot_sd_attackers() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); if ( level.gametype != "sd" ) return; - - if(self.team != game["attackers"]) + + if ( self.team != game["attackers"] ) return; data = spawnStruct(); - data.rand = randomInt(100); + data.rand = randomInt( 100 ); data.first = true; for ( ;; ) { - self bot_sd_attackers_loop(data); + self bot_sd_attackers_loop( data ); } } @@ -4272,119 +4359,124 @@ bot_cap_loop() { myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + myflag = level.teamFlags[myteam]; myzone = level.teamFlagZones[myteam]; - + theirflag = level.teamFlags[otherTeam]; theirzone = level.teamFlagZones[otherTeam]; - - if(myflag maps\mp\gametypes\_gameobjects::isObjectAwayFromHome()) + + if ( myflag maps\mp\gametypes\_gameobjects::isObjectAwayFromHome() ) { carrier = myflag.carrier; - - if(!isDefined(carrier))//someone doesnt has our flag + + if ( !isDefined( carrier ) ) //someone doesnt has our flag { - if(!isDefined(theirflag.carrier) && DistanceSquared(self.origin, theirflag.curorigin) < DistanceSquared(self.origin, myflag.curorigin)) //no one has their flag and its closer - self bot_cap_get_flag(theirflag); + if ( !isDefined( theirflag.carrier ) && DistanceSquared( self.origin, theirflag.curorigin ) < DistanceSquared( self.origin, myflag.curorigin ) ) //no one has their flag and its closer + self bot_cap_get_flag( theirflag ); else//go get it - self bot_cap_get_flag(myflag); - + self bot_cap_get_flag( myflag ); + return; } else { - if(!theirflag maps\mp\gametypes\_gameobjects::isObjectAwayFromHome() && randomint(100) < 50) - { //take their flag - self bot_cap_get_flag(theirflag); + if ( !theirflag maps\mp\gametypes\_gameobjects::isObjectAwayFromHome() && randomint( 100 ) < 50 ) + { + //take their flag + self bot_cap_get_flag( theirflag ); } else { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(!isDefined(theirzone.bots)) + + if ( !isDefined( theirzone.bots ) ) theirzone.bots = 0; - + origin = theirzone.curorigin; - - if(theirzone.bots > 2 || randomInt(100) < 45) + + if ( theirzone.bots > 2 || randomInt( 100 ) < 45 ) { //kill carrier - if(carrier hasPerk( "specialty_gpsjammer" )) + if ( carrier hasPerk( "specialty_gpsjammer" ) ) return; - - origin = carrier.origin; - - self SetBotGoal( origin, 64 ); - self thread bot_escort_obj(myflag, carrier); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + origin = carrier.origin; + + self SetBotGoal( origin, 64 ); + self thread bot_escort_obj( myflag, carrier ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - - self thread bot_inc_bots(theirzone); - + + self thread bot_inc_bots( theirzone ); + //camp their zone - if(DistanceSquared(origin, self.origin) <= 1024*1024) + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) { wait 4; - self notify("bot_inc_bots"); theirzone.bots--; + self notify( "bot_inc_bots" ); + theirzone.bots--; return; } - + self SetBotGoal( origin, 256 ); - self thread bot_inc_bots(theirzone); - self thread bot_escort_obj(myflag, carrier); - - if(self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_inc_bots( theirzone ); + self thread bot_escort_obj( myflag, carrier ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } } } else//our flag is ok { - if(self isFlagCarrier())//if have flag + if ( self isFlagCarrier() ) //if have flag { //go cap origin = myzone.curorigin; - + self.bot_lock_goal = true; self SetBotGoal( origin, 32 ); - self thread bot_get_obj(myflag); + self thread bot_get_obj( myflag ); evt = self waittill_any_return( "goal", "bad_path", "new_goal" ); - + wait 1; - if (evt != "new_goal") + + if ( evt != "new_goal" ) self ClearBotGoal(); + self.bot_lock_goal = false; return; } - + carrier = theirflag.carrier; - - if(!isDefined(carrier))//if no one has enemy flag + + if ( !isDefined( carrier ) ) //if no one has enemy flag { - self bot_cap_get_flag(theirflag); + self bot_cap_get_flag( theirflag ); return; } - - //escort them - - if(self HasScriptGoal()) - return; - - origin = carrier.origin; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) - return; - - self SetBotGoal( origin, 256 ); - self thread bot_escort_obj(theirflag, carrier); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + //escort them + + if ( self HasScriptGoal() ) + return; + + origin = carrier.origin; + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) + return; + + self SetBotGoal( origin, 256 ); + self thread bot_escort_obj( theirflag, carrier ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); } } @@ -4396,7 +4488,7 @@ bot_cap() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); if ( level.gametype != "ctf" ) return; @@ -4404,16 +4496,16 @@ bot_cap() for ( ;; ) { wait( randomintrange( 3, 5 ) ); - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { continue; } - - if(!isDefined(level.teamFlagZones)) + + if ( !isDefined( level.teamFlagZones ) ) continue; - - if(!isDefined(level.teamFlags)) + + if ( !isDefined( level.teamFlags ) ) continue; self bot_cap_loop(); @@ -4423,53 +4515,54 @@ bot_cap() /* Bots go and get the flag */ -bot_cap_get_flag(flag) +bot_cap_get_flag( flag ) { origin = flag.curorigin; - + //go get it - + self.bot_lock_goal = true; self SetBotGoal( origin, 32 ); - - self thread bot_get_obj(flag); + + self thread bot_get_obj( flag ); evt = self waittill_any_return( "goal", "bad_path", "new_goal" ); wait 1; - + self.bot_lock_goal = false; - if (evt != "new_goal") + + if ( evt != "new_goal" ) self ClearBotGoal(); } /* Bots go plant the demo bomb */ -bot_dem_go_plant(plant) +bot_dem_go_plant( plant ) { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 0.5; - if ((plant.label == "_b" && level.bombBPlanted) || (plant.label == "_a" && level.bombAPlanted)) + if ( ( plant.label == "_b" && level.bombBPlanted ) || ( plant.label == "_a" && level.bombAPlanted ) ) break; - if (self isTouching(plant.trigger)) + if ( self isTouching( plant.trigger ) ) break; } - - if((plant.label == "_b" && level.bombBPlanted) || (plant.label == "_a" && level.bombAPlanted)) - self notify("bad_path"); + + if ( ( plant.label == "_b" && level.bombBPlanted ) || ( plant.label == "_a" && level.bombAPlanted ) ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* @@ -4479,23 +4572,23 @@ bot_dem_attack_spawnkill() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - + l1 = level.bombAPlanted; l2 = level.bombBPlanted; - for (;;) + for ( ;; ) { wait 0.5; - if (l1 != level.bombAPlanted || l2 != level.bombBPlanted) + if ( l1 != level.bombAPlanted || l2 != level.bombBPlanted ) break; } - - self notify("bad_path"); + + self notify( "bad_path" ); } /* @@ -4505,185 +4598,190 @@ bot_dem_attackers_loop() { myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + bombs = [];//sites with bombs sites = [];//sites to bomb at bombed = 0;//exploded sites + for ( i = 0; i < level.bombZones.size; i++ ) { bomb = level.bombZones[i]; - - if(isDefined(bomb.bombExploded) && bomb.bombExploded) + + if ( isDefined( bomb.bombExploded ) && bomb.bombExploded ) { bombed++; continue; } - - if(bomb.label == "_a") + + if ( bomb.label == "_a" ) { - if(level.bombAPlanted) + if ( level.bombAPlanted ) bombs[bombs.size] = bomb; else sites[sites.size] = bomb; - + continue; } - - if(bomb.label == "_b") + + if ( bomb.label == "_b" ) { - if(level.bombBPlanted) + if ( level.bombBPlanted ) bombs[bombs.size] = bomb; else sites[sites.size] = bomb; - + continue; } } - timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining()/1000; - - shouldLet = (game["teamScores"][myteam] > game["teamScores"][otherTeam] && timeleft < 90 && bombed == 1); + + timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining() / 1000; + + shouldLet = ( game["teamScores"][myteam] > game["teamScores"][otherTeam] && timeleft < 90 && bombed == 1 ); + //spawnkill conditions //if we have bombed one site or 1 bomb is planted with lots of time left, spawn kill //if we want the other team to win for overtime and they do not need to defuse, spawn kill - if(((bombed + bombs.size == 1 && timeleft >= 90) || (shouldLet && !bombs.size)) && randomInt(100) < 95) + if ( ( ( bombed + bombs.size == 1 && timeleft >= 90 ) || ( shouldLet && !bombs.size ) ) && randomInt( 100 ) < 95 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - + spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dem_spawn_defender_start" ); - - if(!spawnPoints.size) + + if ( !spawnPoints.size ) return; - + spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); - - if(DistanceSquared(spawnpoint.origin, self.origin) <= 2048*2048) + + if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 2048 * 2048 ) return; - + self SetBotGoal( spawnpoint.origin, 1024 ); - + self thread bot_dem_attack_spawnkill(); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - + //let defuse conditions //if enemy is going to lose and lots of time left, let them defuse to play longer //or if want to go into overtime near end of the extended game - if(((bombs.size + bombed == 2 && timeleft >= 90) || (shouldLet && bombs.size)) && randomInt(100) < 95) + if ( ( ( bombs.size + bombed == 2 && timeleft >= 90 ) || ( shouldLet && bombs.size ) ) && randomInt( 100 ) < 95 ) { spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dem_spawn_attacker_start" ); - - if(!spawnPoints.size) + + if ( !spawnPoints.size ) return; - + spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); - - if(DistanceSquared(spawnpoint.origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( spawnpoint.origin, 512 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //defend bomb conditions //if time is running out and we have a bomb planted - if(bombs.size && timeleft < 90 && (!sites.size || randomInt(100) < 95)) + if ( bombs.size && timeleft < 90 && ( !sites.size || randomInt( 100 ) < 95 ) ) { - site = self bot_array_nearest_curorigin(bombs); - origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+32 ); - - if(site IsInUse())//somebody is defusing + site = self bot_array_nearest_curorigin( bombs ); + origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 32 ); + + if ( site IsInUse() ) //somebody is defusing { self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - - self thread bot_defend_site(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + self thread bot_defend_site( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else hang around the site - if(DistanceSquared(origin, self.origin) <= 1024*1024) + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( origin, 256 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else go plant - if(!sites.size) + if ( !sites.size ) return; - - plant = self bot_array_nearest_curorigin(sites); - - if(!isDefined(plant)) + + plant = self bot_array_nearest_curorigin( sites ); + + if ( !isDefined( plant ) ) return; - - if(!isDefined(plant.bots)) + + if ( !isDefined( plant.bots ) ) plant.bots = 0; - - origin = ( plant.curorigin[0]+50, plant.curorigin[1]+50, plant.curorigin[2]+32 ); - + + origin = ( plant.curorigin[0] + 50, plant.curorigin[1] + 50, plant.curorigin[2] + 32 ); + //hang around the site if lots of time left - if(plant.bots > 1 && timeleft >= 60) + if ( plant.bots > 1 && timeleft >= 60 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - self thread bot_dem_go_plant(plant); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + self thread bot_dem_go_plant( plant ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - + self.bot_lock_goal = true; - + self SetBotGoal( origin, 1 ); - self thread bot_inc_bots(plant); - self thread bot_dem_go_plant(plant); - + self thread bot_inc_bots( plant ); + self thread bot_dem_go_plant( plant ); + event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if(event != "goal" || (plant.label == "_b" && level.bombBPlanted) || (plant.label == "_a" && level.bombAPlanted) || plant IsInUse() || !self isTouching(plant.trigger) || self InLastStand() || isDefined(self getThreat())) + + if ( event != "goal" || ( plant.label == "_b" && level.bombBPlanted ) || ( plant.label == "_a" && level.bombAPlanted ) || plant IsInUse() || !self isTouching( plant.trigger ) || self InLastStand() || isDefined( self getThreat() ) ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - self bot_use_bomb_thread(plant); + + self bot_use_bomb_thread( plant ); wait 1; - + self ClearBotGoal(); - + self.bot_lock_goal = false; } @@ -4694,24 +4792,24 @@ bot_dem_attackers() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); if ( level.gametype != "dem" ) return; - - if(self.team != game["attackers"]) + + if ( self.team != game["attackers"] ) return; for ( ;; ) { wait( randomintrange( 3, 5 ) ); - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { continue; } - - if(!isDefined(level.bombZones) || !level.bombZones.size) + + if ( !isDefined( level.bombZones ) || !level.bombZones.size ) continue; self bot_dem_attackers_loop(); @@ -4725,189 +4823,193 @@ bot_dem_defenders_loop() { myTeam = self.pers[ "team" ]; otherTeam = getOtherTeam( myTeam ); - + bombs = [];//sites with bombs sites = [];//sites to bomb at bombed = 0;//exploded sites + for ( i = 0; i < level.bombZones.size; i++ ) { bomb = level.bombZones[i]; - - if(isDefined(bomb.bombExploded) && bomb.bombExploded) + + if ( isDefined( bomb.bombExploded ) && bomb.bombExploded ) { bombed++; continue; } - - if(bomb.label == "_a") + + if ( bomb.label == "_a" ) { - if(level.bombAPlanted) + if ( level.bombAPlanted ) bombs[bombs.size] = bomb; else sites[sites.size] = bomb; - + continue; } - - if(bomb.label == "_b") + + if ( bomb.label == "_b" ) { - if(level.bombBPlanted) + if ( level.bombBPlanted ) bombs[bombs.size] = bomb; else sites[sites.size] = bomb; - + continue; } } - timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining()/1000; - - shouldLet = (timeleft < 60 && ((bombed == 0 && bombs.size != 2) || (game["teamScores"][myteam] > game["teamScores"][otherTeam] && bombed == 1)) && randomInt(100) < 98); - + + timeleft = maps\mp\gametypes\_globallogic_utils::getTimeRemaining() / 1000; + + shouldLet = ( timeleft < 60 && ( ( bombed == 0 && bombs.size != 2 ) || ( game["teamScores"][myteam] > game["teamScores"][otherTeam] && bombed == 1 ) ) && randomInt( 100 ) < 98 ); + //spawnkill conditions //if nothing to defuse with a lot of time left, spawn kill //or letting a bomb site to explode but a bomb is planted, so spawnkill - if((!bombs.size && timeleft >= 60 && randomInt(100) < 95) || (shouldLet && bombs.size == 1)) + if ( ( !bombs.size && timeleft >= 60 && randomInt( 100 ) < 95 ) || ( shouldLet && bombs.size == 1 ) ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - + spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dem_spawn_attacker_start" ); - - if(!spawnPoints.size) + + if ( !spawnPoints.size ) return; - + spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); - - if(DistanceSquared(spawnpoint.origin, self.origin) <= 2048*2048) + + if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 2048 * 2048 ) return; - + self SetBotGoal( spawnpoint.origin, 1024 ); - + self thread bot_dem_defend_spawnkill(); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - + //let blow up conditions //let enemy blow up at least one to extend play time //or if want to go into overtime after extended game - if(shouldLet) + if ( shouldLet ) { spawnPoints = maps\mp\gametypes\_spawnlogic::getSpawnpointArray( "mp_dem_spawn_defender_start" ); - - if(!spawnPoints.size) + + if ( !spawnPoints.size ) return; - + spawnpoint = maps\mp\gametypes\_spawnlogic::getSpawnpoint_Random( spawnPoints ); - - if(DistanceSquared(spawnpoint.origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( spawnpoint.origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( spawnpoint.origin, 512 ); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //defend conditions //if no bombs planted with little time left - if(!bombs.size && timeleft < 60 && randomInt(100) < 95 && sites.size) + if ( !bombs.size && timeleft < 60 && randomInt( 100 ) < 95 && sites.size ) { - site = self bot_array_nearest_curorigin(sites); - origin = ( site.curorigin[0]+50, site.curorigin[1]+50, site.curorigin[2]+32 ); - - if(site IsInUse())//somebody is planting + site = self bot_array_nearest_curorigin( sites ); + origin = ( site.curorigin[0] + 50, site.curorigin[1] + 50, site.curorigin[2] + 32 ); + + if ( site IsInUse() ) //somebody is planting { self.bot_lock_goal = true; self SetBotGoal( origin, 64 ); - - self thread bot_defend_site(site); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + self thread bot_defend_site( site ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else hang around the site - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self.bot_lock_goal = true; self SetBotGoal( origin, 256 ); - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); - + self.bot_lock_goal = false; return; } - + //else go defuse - - if(!bombs.size) + + if ( !bombs.size ) return; - - defuse = self bot_array_nearest_curorigin(bombs); - - if(!isDefined(defuse)) + + defuse = self bot_array_nearest_curorigin( bombs ); + + if ( !isDefined( defuse ) ) return; - - if(!isDefined(defuse.bots)) + + if ( !isDefined( defuse.bots ) ) defuse.bots = 0; - - origin = ( defuse.curorigin[0]+50, defuse.curorigin[1]+50, defuse.curorigin[2]+32 ); - + + origin = ( defuse.curorigin[0] + 50, defuse.curorigin[1] + 50, defuse.curorigin[2] + 32 ); + //hang around the site if not in danger of losing - if(defuse.bots > 1 && bombed + bombs.size != 2) + if ( defuse.bots > 1 && bombed + bombs.size != 2 ) { - if(self HasScriptGoal()) + if ( self HasScriptGoal() ) return; - - if(DistanceSquared(origin, self.origin) <= 1024*1024) + + if ( DistanceSquared( origin, self.origin ) <= 1024 * 1024 ) return; - + self SetBotGoal( origin, 256 ); - - self thread bot_dem_go_defuse(defuse); - - if (self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal") + + self thread bot_dem_go_defuse( defuse ); + + if ( self waittill_any_return( "goal", "bad_path", "new_goal" ) != "new_goal" ) self ClearBotGoal(); + return; } - + self.bot_lock_goal = true; self SetBotGoal( origin, 1 ); - self thread bot_inc_bots(defuse); - self thread bot_dem_go_defuse(defuse); + self thread bot_inc_bots( defuse ); + self thread bot_dem_go_defuse( defuse ); event = self waittill_any_return( "goal", "bad_path", "new_goal" ); - if (event != "new_goal") + if ( event != "new_goal" ) self ClearBotGoal(); - - if(event != "goal" || (defuse.label == "_b" && !level.bombBPlanted) || (defuse.label == "_a" && !level.bombAPlanted) || defuse IsInUse() || !self isTouching(defuse.trigger) || self InLastStand() || isDefined(self getThreat())) + + if ( event != "goal" || ( defuse.label == "_b" && !level.bombBPlanted ) || ( defuse.label == "_a" && !level.bombAPlanted ) || defuse IsInUse() || !self isTouching( defuse.trigger ) || self InLastStand() || isDefined( self getThreat() ) ) { self.bot_lock_goal = false; return; } - + self SetBotGoal( self.origin, 64 ); - - self bot_use_bomb_thread(defuse); + + self bot_use_bomb_thread( defuse ); wait 1; - + self ClearBotGoal(); - + self.bot_lock_goal = false; } @@ -4918,24 +5020,24 @@ bot_dem_defenders() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); if ( level.gametype != "dem" ) return; - - if(self.team == game["attackers"]) + + if ( self.team == game["attackers"] ) return; for ( ;; ) { wait( randomintrange( 3, 5 ) ); - + if ( self IsRemoteControlling() || self.bot_lock_goal ) { continue; } - - if(!isDefined(level.bombZones) || !level.bombZones.size) + + if ( !isDefined( level.bombZones ) || !level.bombZones.size ) continue; self bot_dem_defenders_loop(); @@ -4945,30 +5047,30 @@ bot_dem_defenders() /* Bots go defuse */ -bot_dem_go_defuse(defuse) +bot_dem_go_defuse( defuse ) { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 0.5; - if (self isTouching(defuse.trigger)) + if ( self isTouching( defuse.trigger ) ) break; - if ((defuse.label == "_b" && !level.bombBPlanted) || (defuse.label == "_a" && !level.bombAPlanted)) + 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"); + + if ( ( defuse.label == "_b" && !level.bombBPlanted ) || ( defuse.label == "_a" && !level.bombAPlanted ) ) + self notify( "bad_path" ); else - self notify("goal"); + self notify( "goal" ); } /* @@ -4978,18 +5080,18 @@ bot_dem_defend_spawnkill() { self endon( "death" ); self endon( "disconnect" ); - level endon("game_ended"); + level endon( "game_ended" ); self endon( "goal" ); self endon( "bad_path" ); self endon( "new_goal" ); - for (;;) + for ( ;; ) { wait 0.5; - if (level.bombBPlanted || level.bombAPlanted) + if ( level.bombBPlanted || level.bombAPlanted ) break; } - - self notify("bad_path"); + + self notify( "bad_path" ); } diff --git a/main_shared/maps/mp/bots/_bot_utility.gsc b/main_shared/maps/mp/bots/_bot_utility.gsc index 1daa762..2cc8089 100644 --- a/main_shared/maps/mp/bots/_bot_utility.gsc +++ b/main_shared/maps/mp/bots/_bot_utility.gsc @@ -16,16 +16,17 @@ getBotArray() { result = []; playercount = level.players.size; - for(i = 0; i < playercount; i++) + + for ( i = 0; i < playercount; i++ ) { player = level.players[i]; - - if(!player is_bot()) + + if ( !player is_bot() ) continue; - + result[result.size] = player; } - + return result; } @@ -34,7 +35,7 @@ getBotArray() */ getGoodMapAmount() { - switch(getdvar("mapname")) + switch ( getdvar( "mapname" ) ) { default: return 2; @@ -44,13 +45,13 @@ getGoodMapAmount() /* Rounds to the nearest whole number. */ -Round(x) +Round( x ) { - y = int(x); - - if(abs(x) - abs(y) > 0.5) + y = int( x ); + + if ( abs( x ) - abs( y ) > 0.5 ) { - if(x < 0) + if ( x < 0 ) return y - 1; else return y + 1; @@ -62,12 +63,12 @@ Round(x) /* Picks a random thing */ -PickRandom(arr) +PickRandom( arr ) { - if (!arr.size) + if ( !arr.size ) return undefined; - return arr[randomInt(arr.size)]; + return arr[randomInt( arr.size )]; } /* @@ -75,7 +76,7 @@ PickRandom(arr) */ isDefusing() { - return (isDefined(self.isDefusing) && self.isDefusing); + return ( isDefined( self.isDefusing ) && self.isDefusing ); } /* @@ -83,7 +84,7 @@ isDefusing() */ isPlanting() { - return (isDefined(self.isPlanting) && self.isPlanting); + return ( isDefined( self.isPlanting ) && self.isPlanting ); } /* @@ -91,7 +92,7 @@ isPlanting() */ inLastStand() { - return (isDefined(self.laststand) && self.laststand); + return ( isDefined( self.laststand ) && self.laststand ); } /* @@ -99,7 +100,7 @@ inLastStand() */ isFlagCarrier() { - return (isDefined(self.isFlagCarrier) && self.isFlagCarrier); + return ( isDefined( self.isFlagCarrier ) && self.isFlagCarrier ); } /* @@ -107,7 +108,7 @@ isFlagCarrier() */ isInUse() { - return (isDefined(self.inUse) && self.inUse); + return ( isDefined( self.inUse ) && self.inUse ); } /* @@ -115,7 +116,7 @@ isInUse() */ isBombCarrier() { - return (isDefined(self.isBombCarrier) && self.isBombCarrier); + return ( isDefined( self.isBombCarrier ) && self.isBombCarrier ); } /* @@ -141,17 +142,20 @@ GetBotDiffNum() { num = 0; - switch (getDvar("bot_difficulty")) + switch ( getDvar( "bot_difficulty" ) ) { case "fu": num = 3; break; + case "hard": num = 2; break; + case "normal": num = 1; break; + case "easy": default: num = 0; @@ -164,9 +168,9 @@ GetBotDiffNum() /* is the weapon alt mode? */ -isWeaponAltmode(weap) +isWeaponAltmode( weap ) { - if (isStrStart(weap, "gl_") || isStrStart(weap, "ft_") || isStrStart(weap, "mk_")) + if ( isStrStart( weap, "gl_" ) || isStrStart( weap, "ft_" ) || isStrStart( weap, "mk_" ) ) return true; return false; @@ -179,14 +183,14 @@ getValidTube() { weaps = self getweaponslist(); - for (i = 0; i < weaps.size; i++) + for ( i = 0; i < weaps.size; i++ ) { weap = weaps[i]; - if(!self getAmmoCount(weap)) + if ( !self getAmmoCount( weap ) ) continue; - if ((isSubStr(weap, "gl_") && !isSubStr(weap, "_gl_")) || weap == "china_lake_mp") + if ( ( isSubStr( weap, "gl_" ) && !isSubStr( weap, "_gl_" ) ) || weap == "china_lake_mp" ) return weap; } @@ -199,10 +203,10 @@ getValidTube() waittill_any_timeout( timeOut, string1, string2, string3, string4, string5 ) { if ( ( !isdefined( string1 ) || string1 != "death" ) && - ( !isdefined( string2 ) || string2 != "death" ) && - ( !isdefined( string3 ) || string3 != "death" ) && - ( !isdefined( string4 ) || string4 != "death" ) && - ( !isdefined( string5 ) || string5 != "death" ) ) + ( !isdefined( string2 ) || string2 != "death" ) && + ( !isdefined( string3 ) || string3 != "death" ) && + ( !isdefined( string4 ) || string4 != "death" ) && + ( !isdefined( string5 ) || string5 != "death" ) ) self endon( "death" ); ent = spawnstruct(); @@ -247,38 +251,38 @@ bot_wait_for_host() { host = undefined; - while (!isDefined(level) || !isDefined(level.players)) + while ( !isDefined( level ) || !isDefined( level.players ) ) wait 0.05; - - for(i = getDvarFloat("bots_main_waitForHostTime"); i > 0; i -= 0.05) + + for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { host = GetHostPlayer(); - - if(isDefined(host)) + + if ( isDefined( host ) ) break; - - wait 0.05; - } - - if(!isDefined(host)) - 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" ] )) + if ( !isDefined( host ) ) return; - - for(i = getDvarFloat("bots_main_waitForHostTime"); i > 0; i -= 0.05) + + for ( i = getDvarFloat( "bots_main_waitForHostTime" ); i > 0; i -= 0.05 ) { - if(host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis") + 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; } } @@ -286,11 +290,11 @@ bot_wait_for_host() /* Wrapper for setgoal */ -SetBotGoal(where, dist) +SetBotGoal( where, dist ) { - self SetScriptGoal(where, dist); + self SetScriptGoal( where, dist ); waittillframeend; - self notify("new_goal"); + self notify( "new_goal" ); } /* @@ -300,29 +304,30 @@ ClearBotGoal() { self ClearScriptGoal(); waittillframeend; - self notify("new_goal"); + self notify( "new_goal" ); } /* Freezes bot in place */ -botStopMove(what) +botStopMove( what ) { - self endon("disconnect"); - self endon("death"); - level endon("game_ended"); + self endon( "disconnect" ); + self endon( "death" ); + level endon( "game_ended" ); - self notify("botStopMove"); - self endon("botStopMove"); + self notify( "botStopMove" ); + self endon( "botStopMove" ); - if (!what) + if ( !what ) return; og = self.origin; - for (;;) + + for ( ;; ) { - self setVelocity((0,0,0)); - self setOrigin(og); + self setVelocity( ( 0, 0, 0 ) ); + self setOrigin( og ); wait 0.05; } } @@ -330,40 +335,125 @@ botStopMove(what) /* Matches a num to a char */ -keyCodeToString(a) +keyCodeToString( a ) { - b=""; - switch(a) + b = ""; + + switch ( a ) { - case 0: b= "a"; break; - case 1: b= "b"; break; - case 2: b= "c"; break; - case 3: b= "d"; break; - case 4: b= "e"; break; - case 5: b= "f"; break; - case 6: b= "g"; break; - case 7: b= "h"; break; - case 8: b= "i"; break; - case 9: b= "j"; break; - case 10: b= "k"; break; - case 11: b= "l"; break; - case 12: b= "m"; break; - case 13: b= "n"; break; - case 14: b= "o"; break; - case 15: b= "p"; break; - case 16: b= "q"; break; - case 17: b= "r"; break; - case 18: b= "s"; break; - case 19: b= "t"; break; - case 20: b= "u"; break; - case 21: b= "v"; break; - case 22: b= "w"; break; - case 23: b= "x"; break; - case 24: b= "y"; break; - case 25: b= "z"; break; - case 26: b= "."; break; - case 27: b= " "; break; + case 0: + b = "a"; + break; + + case 1: + b = "b"; + break; + + case 2: + b = "c"; + break; + + case 3: + b = "d"; + break; + + case 4: + b = "e"; + break; + + case 5: + b = "f"; + break; + + case 6: + b = "g"; + break; + + case 7: + b = "h"; + break; + + case 8: + b = "i"; + break; + + case 9: + b = "j"; + break; + + case 10: + b = "k"; + break; + + case 11: + b = "l"; + break; + + case 12: + b = "m"; + break; + + case 13: + b = "n"; + break; + + case 14: + b = "o"; + break; + + case 15: + b = "p"; + break; + + case 16: + b = "q"; + break; + + case 17: + b = "r"; + break; + + case 18: + b = "s"; + break; + + case 19: + b = "t"; + break; + + case 20: + b = "u"; + break; + + case 21: + b = "v"; + break; + + case 22: + b = "w"; + break; + + case 23: + b = "x"; + break; + + case 24: + b = "y"; + break; + + case 25: + b = "z"; + break; + + case 26: + b = "."; + break; + + case 27: + b = " "; + break; } + return b; } @@ -378,11 +468,11 @@ doExtraCheck() /* Returns the cone dot (like fov, or distance from the center of our screen). */ -getConeDot(to, from, dir) +getConeDot( to, from, dir ) { - dirToTarget = VectorNormalize(to-from); - forward = AnglesToForward(dir); - return vectordot(dirToTarget, forward); + dirToTarget = VectorNormalize( to - from ); + forward = AnglesToForward( dir ); + return vectordot( dirToTarget, forward ); } /* @@ -395,23 +485,24 @@ bot_onUsePlantObjectFix( player ) { level thread bot_bombPlanted( self, player ); player logString( "bomb planted: " + self.label ); - + // disable all bomb zones except this one for ( index = 0; index < level.bombZones.size; index++ ) { if ( level.bombZones[index] == self ) continue; - + level.bombZones[index] maps\mp\gametypes\_gameobjects::disableObject(); } - thread playSoundOnPlayers( "mus_sd_planted"+"_"+level.teamPostfix[player.pers["team"]] ); -// removed plant audio until finalization of assest TODO : new plant sounds when assests are online + + thread playSoundOnPlayers( "mus_sd_planted" + "_" + level.teamPostfix[player.pers["team"]] ); +// removed plant audio until finalization of assest TODO : new plant sounds when assests are online // player playSound( "mpl_sd_bomb_plant" ); player notify ( "bomb_planted" ); - + level thread maps\mp\_popups::DisplayTeamMessageToAll( &"MP_EXPLOSIVES_PLANTED_BY", player ); - if( isdefined(player.pers["plants"]) ) + if ( isdefined( player.pers["plants"] ) ) { player.pers["plants"]++; player.plants = player.pers["plants"]; @@ -419,7 +510,7 @@ bot_onUsePlantObjectFix( player ) player maps\mp\_medals::saboteur(); player maps\mp\gametypes\_persistence::statAddWithGameType( "PLANTS", 1 ); - + maps\mp\gametypes\_globallogic_audio::leaderDialog( "bomb_planted" ); maps\mp\gametypes\_globallogic_score::givePlayerScore( "plant", player ); @@ -434,19 +525,19 @@ bot_bombPlanted( destroyedObj, player ) { maps\mp\gametypes\_globallogic_utils::pauseTimer(); level.bombPlanted = true; - + destroyedObj.visuals[0] thread maps\mp\gametypes\_globallogic_utils::playTickingSound( "mpl_sab_ui_suitcasebomb_timer" ); //Play suspense music level thread maps\mp\gametypes\sd::bombPlantedMusicDelay(); - //thread maps\mp\gametypes\_globallogic_audio::actionMusicSet(); - + //thread maps\mp\gametypes\_globallogic_audio::actionMusicSet(); + level.tickingObject = destroyedObj.visuals[0]; level.timeLimitOverride = true; - setGameEndTime( int( gettime() + (level.bombTimer * 1000) ) ); + setGameEndTime( int( gettime() + ( level.bombTimer * 1000 ) ) ); setMatchFlag( "bomb_timer", 1 ); - + if ( !level.multiBomb ) { level.sdBomb maps\mp\gametypes\_gameobjects::allowCarry( "none" ); @@ -456,39 +547,40 @@ bot_bombPlanted( destroyedObj, player ) } else { - + 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 ); - + trace = bulletTrace( player.origin + ( 0, 0, 20 ), player.origin - ( 0, 0, 2000 ), false, player ); + tempAngle = randomfloat( 360 ); - forward = (cos( tempAngle ), sin( tempAngle ), 0); + forward = ( cos( tempAngle ), sin( tempAngle ), 0 ); forward = vectornormalize( forward - vector_scale( trace["normal"], vectordot( forward, trace["normal"] ) ) ); dropAngles = vectortoangles( forward ); - + level.sdBombModel = spawn( "script_model", trace["position"] ); level.sdBombModel.angles = dropAngles; level.sdBombModel setModel( "prop_suitcase_bomb" ); } + destroyedObj maps\mp\gametypes\_gameobjects::allowUse( "none" ); destroyedObj maps\mp\gametypes\_gameobjects::setVisibleTeam( "none" ); /* - destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined ); - destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined ); - destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined ); - destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined ); + destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "friendly", undefined ); + destroyedObj maps\mp\gametypes\_gameobjects::set2DIcon( "enemy", undefined ); + destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "friendly", undefined ); + destroyedObj maps\mp\gametypes\_gameobjects::set3DIcon( "enemy", undefined ); */ label = destroyedObj maps\mp\gametypes\_gameobjects::getLabel(); - + // create a new object to defuse with. trigger = destroyedObj.bombDefuseTrig; trigger.origin = level.sdBombModel.origin; visuals = []; - defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, (0,0,32) ); + defuseObject = maps\mp\gametypes\_gameobjects::createUseObject( game["defenders"], trigger, visuals, ( 0, 0, 32 ) ); defuseObject maps\mp\gametypes\_gameobjects::allowUse( "friendly" ); defuseObject maps\mp\gametypes\_gameobjects::setUseTime( level.defuseTime ); defuseObject maps\mp\gametypes\_gameobjects::setUseText( &"MP_DEFUSING_EXPLOSIVE" ); @@ -503,26 +595,26 @@ bot_bombPlanted( destroyedObj, player ) defuseObject.onEndUse = maps\mp\gametypes\sd::onEndUse; defuseObject.onUse = maps\mp\gametypes\sd::onUseDefuseObject; defuseObject.useWeapon = "briefcase_bomb_defuse_mp"; - + level.defuseObject = defuseObject;//every cod... - + player.isBombCarrier = false; - + maps\mp\gametypes\sd::BombTimerWait(); setMatchFlag( "bomb_timer", 0 ); - + destroyedObj.visuals[0] maps\mp\gametypes\_globallogic_utils::stopTickingSound(); - + if ( level.gameEnded || level.bombDefused ) return; - + level.bombExploded = true; - - - - explosionOrigin = level.sdBombModel.origin+(0,0,12); + + + + explosionOrigin = level.sdBombModel.origin + ( 0, 0, 12 ); level.sdBombModel hide(); - + if ( isdefined( player ) ) { destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, player, "MOD_EXPLOSIVE", "briefcase_bomb_mp" ); @@ -532,24 +624,25 @@ bot_bombPlanted( destroyedObj, player ) } else destroyedObj.visuals[0] radiusDamage( explosionOrigin, 512, 200, 20, undefined, "MOD_EXPLOSIVE", "briefcase_bomb_mp" ); - - rot = randomfloat(360); - explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + (0,0,50), (0,0,1), (cos(rot),sin(rot),0) ); + + rot = randomfloat( 360 ); + explosionEffect = spawnFx( level._effect["bombexplosion"], explosionOrigin + ( 0, 0, 50 ), ( 0, 0, 1 ), ( cos( rot ), sin( rot ), 0 ) ); triggerFx( explosionEffect ); - + thread playSoundinSpace( "mpl_sd_exp_suitcase_bomb_main", explosionOrigin ); - //thread maps\mp\gametypes\_globallogic_audio::set_music_on_team( "SILENT", "both" ); - + //thread maps\mp\gametypes\_globallogic_audio::set_music_on_team( "SILENT", "both" ); + 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(); - + setGameEndTime( 0 ); - + wait 3; - + maps\mp\gametypes\sd::sd_endGame( game["attackers"], game["strings"]["target_destroyed"] ); } diff --git a/main_shared/maps/mp/gametypes/_bot.gsc b/main_shared/maps/mp/gametypes/_bot.gsc index e4c6876..1719cfa 100644 --- a/main_shared/maps/mp/gametypes/_bot.gsc +++ b/main_shared/maps/mp/gametypes/_bot.gsc @@ -1,952 +1,991 @@ -/* - _bot - Author: INeedGames - Date: 12/20/2020 - The entry point and manager of the bots. -*/ - -#include common_scripts\utility; -#include maps\mp\_utility; -#include maps\mp\gametypes\_hud_util; -#include maps\mp\bots\_bot_utility; - -/* - Entry point to the bots -*/ -init() -{ - level.bw_VERSION = "1.1.1"; - - level.bot_offline = false; - - if(getDvar("bots_main") == "") - setDvar("bots_main", true); - - if (!getDvarInt("bots_main")) - return; - - if(getDvar("bots_main_waitForHostTime") == "") - setDvar("bots_main_waitForHostTime", 10.0);//how long to wait to wait for the host player - - 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_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_codpoints") == "")// how much cod points a bot should have, -1 is around the players, 0 is all random - setDvar("bots_loadout_codpoints", -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_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_nade") == "")//bots grenade - setDvar("bots_play_nade", 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_move") == "")//bots move - setDvar("bots_play_move", 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); - - level.bots = []; - level.bot_decoys = []; - level.bot_planes = []; - - if(!isDefined(game["botWarfare"])) - game["botWarfare"] = true; - - thread fixGamemodes(); - thread onPlayerConnect(); - thread bot_watch_planes(); - - thread handleBots(); - - thread doNonDediBots(); -} - -/* - Thread when any player connects. Starts the threads needed. -*/ -onPlayerConnect() -{ - for(;;) - { - level waittill("connected", player); - - player thread watch_shoot(); - player thread watch_grenade(); - player thread connected(); - } -} - -/* - Starts the threads for bots. -*/ -handleBots() -{ - thread diffBots(); - thread teamBots(); - addBots(); - - while(!level.intermission) - wait 0.05; - - setDvar("bots_manage_add", getBotArray().size); -} - -/* - When a bot disconnects. -*/ -onDisconnect() -{ - self waittill("disconnect"); - - level.bots = array_remove(level.bots, self); -} - -/* - Whena player connects -*/ -connected() -{ - self endon("disconnect"); - - if (!self is_bot()) - return; - - self thread maps\mp\bots\_bot_script::connected(); - - level.bots[level.bots.size] = self; - self thread onDisconnect(); - - level notify("bot_connected", self); -} - -/* - Handles the diff of the bots -*/ -diffBots() -{ - for (;;) - { - wait 1.5; - - bot_set_difficulty(GetDvar( #"bot_difficulty" )); - } -} - -/* - Setup bot dvars for non dedicated clients -*/ -doNonDediBots() -{ - if (!GetDvarInt( #"xblive_basictraining" )) - return; - - if (isDefined(game[ "bots_spawned" ])) - return; - - game[ "bots_spawned" ] = true; - - if(getDvar("bot_enemies_extra") == "") - setDvar("bot_enemies_extra", 0); - if(getDvar("bot_friends_extra") == "") - setDvar("bot_friends_extra", 0); - - bot_friends = GetDvarInt( #"bot_friends" ); - bot_enemies = GetDvarInt( #"bot_enemies" ); - - bot_enemies += GetDvarInt("bot_enemies_extra"); - bot_friends += GetDvarInt("bot_friends_extra"); - - bot_wait_for_host(); - host = GetHostPlayer(); - - team = "allies"; - if(isDefined(host) && isDefined(host.pers[ "team" ]) && (host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis")) - team = host.pers[ "team" ]; - - setDvar("bots_manage_add", bot_enemies + bot_friends - 1); - setDvar("bots_manage_fill", bot_enemies + bot_friends); - setDvar("bots_manage_fill_mode", 0); - setDvar("bots_manage_fill_kick", true); - setDvar("bots_manage_fill_spec", false); - - setDvar("bots_team", "custom"); - - if (team == "axis") - setDvar("bots_team_amount", bot_friends); - else - setDvar("bots_team_amount", bot_enemies); - - setDvar("bots_team_force", true); - setDvar("bots_team_mode", 0); -} - -/* - Sets the difficulty of the bots -*/ -bot_set_difficulty( difficulty ) -{ - if ( difficulty == "fu" ) - { - SetDvar( "sv_botMinDeathTime", "250" ); - SetDvar( "sv_botMaxDeathTime", "500" ); - SetDvar( "sv_botMinFireTime", "100" ); - SetDvar( "sv_botMaxFireTime", "300" ); - SetDvar( "sv_botYawSpeed", "14" ); - SetDvar( "sv_botYawSpeedAds", "14" ); - SetDvar( "sv_botPitchUp", "-5" ); - SetDvar( "sv_botPitchDown", "10" ); - SetDvar( "sv_botFov", "160" ); - SetDvar( "sv_botMinAdsTime", "3000" ); - SetDvar( "sv_botMaxAdsTime", "5000" ); - SetDvar( "sv_botMinCrouchTime", "100" ); - SetDvar( "sv_botMaxCrouchTime", "400" ); - SetDvar( "sv_botTargetLeadBias", "2" ); - SetDvar( "sv_botMinReactionTime", "30" ); - SetDvar( "sv_botMaxReactionTime", "100" ); - SetDvar( "sv_botStrafeChance", "1" ); - SetDvar( "sv_botMinStrafeTime", "3000" ); - SetDvar( "sv_botMaxStrafeTime", "6000" ); - SetDvar( "scr_help_dist", "512" ); - SetDvar( "sv_botAllowGrenades", "1" ); - SetDvar( "sv_botMinGrenadeTime", "1500" ); - SetDvar( "sv_botMaxGrenadeTime", "4000" ); - SetDvar( "sv_botSprintDistance", "512" ); - SetDvar( "sv_botMeleeDist", "80" ); - } - else if ( difficulty == "hard" ) - { - SetDvar( "sv_botMinDeathTime", "250" ); - SetDvar( "sv_botMaxDeathTime", "500" ); - SetDvar( "sv_botMinFireTime", "400" ); - SetDvar( "sv_botMaxFireTime", "600" ); - SetDvar( "sv_botYawSpeed", "8" ); - SetDvar( "sv_botYawSpeedAds", "10" ); - SetDvar( "sv_botPitchUp", "-5" ); - SetDvar( "sv_botPitchDown", "10" ); - SetDvar( "sv_botFov", "100" ); - SetDvar( "sv_botMinAdsTime", "3000" ); - SetDvar( "sv_botMaxAdsTime", "5000" ); - SetDvar( "sv_botMinCrouchTime", "100" ); - SetDvar( "sv_botMaxCrouchTime", "400" ); - SetDvar( "sv_botTargetLeadBias", "2" ); - SetDvar( "sv_botMinReactionTime", "400" ); - SetDvar( "sv_botMaxReactionTime", "700" ); - SetDvar( "sv_botStrafeChance", "0.9" ); - SetDvar( "sv_botMinStrafeTime", "3000" ); - SetDvar( "sv_botMaxStrafeTime", "6000" ); - SetDvar( "scr_help_dist", "384" ); - SetDvar( "sv_botAllowGrenades", "1" ); - SetDvar( "sv_botMinGrenadeTime", "1500" ); - SetDvar( "sv_botMaxGrenadeTime", "4000" ); - SetDvar( "sv_botSprintDistance", "512" ); - SetDvar( "sv_botMeleeDist", "80" ); - } - else if ( difficulty == "easy" ) - { - SetDvar( "sv_botMinDeathTime", "1000" ); - SetDvar( "sv_botMaxDeathTime", "2000" ); - SetDvar( "sv_botMinFireTime", "900" ); - SetDvar( "sv_botMaxFireTime", "1000" ); - SetDvar( "sv_botYawSpeed", "2" ); - SetDvar( "sv_botYawSpeedAds", "2.5" ); - SetDvar( "sv_botPitchUp", "-20" ); - SetDvar( "sv_botPitchDown", "40" ); - SetDvar( "sv_botFov", "50" ); - SetDvar( "sv_botMinAdsTime", "3000" ); - SetDvar( "sv_botMaxAdsTime", "5000" ); - SetDvar( "sv_botMinCrouchTime", "4000" ); - SetDvar( "sv_botMaxCrouchTime", "6000" ); - SetDvar( "sv_botTargetLeadBias", "8" ); - SetDvar( "sv_botMinReactionTime", "1200" ); - SetDvar( "sv_botMaxReactionTime", "1600" ); - SetDvar( "sv_botStrafeChance", "0.1" ); - SetDvar( "sv_botMinStrafeTime", "3000" ); - SetDvar( "sv_botMaxStrafeTime", "6000" ); - SetDvar( "scr_help_dist", "256" ); - SetDvar( "sv_botAllowGrenades", "0" ); - SetDvar( "sv_botSprintDistance", "1024" ); - SetDvar( "sv_botMeleeDist", "40" ); - } - else // 'normal' difficulty - { - SetDvar( "sv_botMinDeathTime", "500" ); - SetDvar( "sv_botMaxDeathTime", "1000" ); - SetDvar( "sv_botMinFireTime", "600" ); - SetDvar( "sv_botMaxFireTime", "800" ); - SetDvar( "sv_botYawSpeed", "4" ); - SetDvar( "sv_botYawSpeedAds", "5" ); - SetDvar( "sv_botPitchUp", "-10" ); - SetDvar( "sv_botPitchDown", "20" ); - SetDvar( "sv_botFov", "70" ); - SetDvar( "sv_botMinAdsTime", "3000" ); - SetDvar( "sv_botMaxAdsTime", "5000" ); - SetDvar( "sv_botMinCrouchTime", "2000" ); - SetDvar( "sv_botMaxCrouchTime", "4000" ); - SetDvar( "sv_botTargetLeadBias", "4" ); - SetDvar( "sv_botMinReactionTime", "800" ); - SetDvar( "sv_botMaxReactionTime", "1200" ); - SetDvar( "sv_botStrafeChance", "0.6" ); - SetDvar( "sv_botMinStrafeTime", "3000" ); - SetDvar( "sv_botMaxStrafeTime", "6000" ); - SetDvar( "scr_help_dist", "256" ); - SetDvar( "sv_botAllowGrenades", "1" ); - SetDvar( "sv_botMinGrenadeTime", "1500" ); - SetDvar( "sv_botMaxGrenadeTime", "4000" ); - SetDvar( "sv_botSprintDistance", "512" ); - SetDvar( "sv_botMeleeDist", "80" ); - difficulty = "normal"; - } - - if ( level.gameType == "oic" && difficulty == "fu" ) - { - SetDvar( "sv_botMinReactionTime", "400" ); - SetDvar( "sv_botMaxReactionTime", "500" ); - SetDvar( "sv_botMinAdsTime", "1000" ); - SetDvar( "sv_botMaxAdsTime", "2000" ); - } - - if ( level.gameType == "oic" && ( difficulty == "hard" || difficulty == "fu" ) ) - { - SetDvar( "sv_botSprintDistance", "256" ); - } - - if (!getDvarInt("bots_play_nade")) - SetDvar( "sv_botAllowGrenades", "0" ); - - SetDvar( "bot_difficulty", difficulty ); - SetDvar( "scr_bot_difficulty", difficulty ); - SetDvar( "splitscreen_botDifficulty", difficulty ); -} - -/* - A server thread for monitoring all bot's teams for custom server settings. -*/ -teamBots_loop() -{ - teamAmount = getDvarInt("bots_team_amount"); - toTeam = getDvar("bots_team"); - - alliesbots = 0; - alliesplayers = 0; - axisbots = 0; - axisplayers = 0; - - playercount = level.players.size; - for(i = 0; i < playercount; i++) - { - 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++; - } - } - - allies = alliesbots; - axis = axisbots; - - if(!getDvarInt("bots_team_mode")) - { - allies += alliesplayers; - axis += axisplayers; - } - - if(toTeam != "custom") - { - if(getDvarInt("bots_team_force")) - { - if(toTeam == "autoassign") - { - if(abs(axis - allies) > 1) - { - toTeam = "axis"; - if(axis > allies) - toTeam = "allies"; - } - } - - if(toTeam != "autoassign") - { - playercount = level.players.size; - for(i = 0; i < playercount; i++) - { - 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; - } - } - } - } - else - { - playercount = level.players.size; - for(i = 0; i < playercount; i++) - { - player = level.players[i]; - - if(!isDefined(player.pers["team"])) - continue; - - if(!player is_bot()) - continue; - - if(player.pers["team"] == "axis") - { - if(axis > teamAmount) - { - player thread [[level.allies]](); - break; - } - } - else - { - if(axis < teamAmount) - { - player thread [[level.axis]](); - break; - } - else if(player.pers["team"] != "allies") - { - player thread [[level.allies]](); - break; - } - } - } - } -} - -/* - A server thread for monitoring all bot's teams for custom server settings. -*/ -teamBots() -{ - for(;;) - { - wait 1.5; - teamBots_loop(); - } -} - -/* - Loop -*/ -addBots_loop() -{ - botsToAdd = GetDvarInt("bots_manage_add"); - - if(botsToAdd > 0) - { - SetDvar("bots_manage_add", 0); - - if(botsToAdd > 64) - botsToAdd = 64; - - for(; botsToAdd > 0; botsToAdd--) - { - level add_bot(); - wait 0.25; - } - } - - fillMode = getDVarInt("bots_manage_fill_mode"); - - if(fillMode == 2 || fillMode == 3) - setDvar("bots_manage_fill", getGoodMapAmount()); - - fillAmount = getDvarInt("bots_manage_fill"); - - players = 0; - bots = 0; - spec = 0; - - playercount = level.players.size; - for(i = 0; i < playercount; i++) - { - player = level.players[i]; - - if (player isdemoclient()) - continue; - - if(player is_bot()) - bots++; - else if(!isDefined(player.pers["team"]) || (player.pers["team"] != "axis" && player.pers["team"] != "allies")) - spec++; - else - players++; - } - - if(fillMode == 4) - { - axisplayers = 0; - alliesplayers = 0; - - playercount = level.players.size; - for(i = 0; i < playercount; i++) - { - 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; - - if (players == 0) - { - if(bots < fillAmount) - result = fillAmount-1; - else if (bots > fillAmount) - result = fillAmount+1; - else - result = fillAmount; - } - - bots = result; - } - - if (!randomInt(999)) - { - setDvar("testclients_doreload", true); - wait 0.1; - setDvar("testclients_doreload", false); - doExtraCheck(); - } - - 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 = PickRandom(getBotArray()); - if (isDefined(tempBot)) - kick( tempBot getEntityNumber(), "EXE_PLAYERKICKED" ); - } -} - -/* - A server thread for monitoring all bot's in game. Will add and kick bots according to server settings. - - Dedis only spawn bots when developer is not 0 - This makes the dedi unstable and can crash - - Patch the executable to skip the pregame and make it so bots can spawn - - pregame: - in the ShouldDoPregame sub: - B8 01 00 00 00: mov eax, 1 -change to: B8 00 00 00 00: mov eax, 0 - 0x4F6C77 in rektmp - 0x4598A7 in bg - - - spawnbots: - in the SV_AddTestClient sub: - 0F 85 A4 00 00 00: jnz -change to: 0F 84 A4 00 00 00: jz - 0x6B6180 in rektmp - 0x4682F0 in bg - - - allow changing g_antilag dvar: - set the byte from 0x40 to 0x00 - - 0x53B1B2 in rekt - 0x59B6F2 in bg -*/ -addBots() -{ - level endon ( "game_ended" ); - - bot_wait_for_host(); - - for (;;) - { - wait 1.5; - - addBots_loop(); - } -} - -/* - Adds a bot to the game. -*/ -add_bot() -{ - bot = addtestclient(); - - if (isdefined(bot)) - { - bot.pers["isBot"] = true; - bot.equipment_enabled = true; - bot.pers[ "bot_perk" ] = true; - bot.pers["isBotWarfare"] = true; - bot thread maps\mp\bots\_bot_script::added(); - } -} - -/* - Gives the bot loadout -*/ -bot_give_loadout() -{ - self maps\mp\bots\_bot_loadout::bot_give_loadout(); -} - -/* - Fired when the bot is damaged -*/ -bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHitLoc ) -{ - self maps\mp\bots\_bot_script::bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHitLoc ); -} - -/* - Bot is idle -*/ -bot_is_idle() -{ - if ( !IsDefined( self ) ) - { - return false; - } - - if ( !IsAlive( self ) ) - { - return false; - } - - if ( !self is_bot() ) - { - return false; - } - - if ( self inLastStand() ) - { - return false; - } - - if ( self HasScriptGoal() ) - { - return false; - } - - if ( IsDefined( self GetThreat() ) ) - { - return false; - } - - if ( self IsRemoteControlling() || self.bot_lock_goal ) - { - return false; - } - - if(self UseButtonPressed()) - return false; - - if(self isPlanting()) - return false; - - if(self isDefusing()) - return false; - - return true; -} - -/* - Watch all players grenades -*/ -watch_grenade() -{ - self endon("disconnect"); - - self.bot_scrambled = false; - for(;;) - { - self waittill("grenade_fire", g, name); - - if (!isDefined(g)) - continue; - - if(name == "scrambler_mp") - { - g thread watch_scrambler(); - } - else if(name == "nightingale_mp") - { - self thread watch_decoy(g); - } - } -} - -/* - Watch the decoy grenade -*/ -watch_decoy(g) -{ - g.team = self.team; - - level.bot_decoys[level.bot_decoys.size] = g; - - g waittill("death"); - - for ( entry = 0; entry < level.bot_decoys.size; entry++ ) - { - if ( level.bot_decoys[entry] == g ) - { - while ( entry < level.bot_decoys.size-1 ) - { - level.bot_decoys[entry] = level.bot_decoys[entry+1]; - entry++; - } - level.bot_decoys[entry] = undefined; - break; - } - } -} - -/* - Attach a trigger to the scrambler -*/ -watch_scrambler() -{ - trig = spawn( "trigger_radius", self.origin + (0, 0, -1000), 0, 1000, 2000 ); - - self scramble_nearby(trig); - - trig delete(); -} - -/* - Watch when players enter the scrambler trigger -*/ -scramble_nearby(trig) -{ - self endon("death"); - self endon("hacked"); - - while(!isDefined(self.owner) || !isDefined(self.owner.team)) - wait 0.05; - - self.team = self.owner.team; - for(;;) - { - trig waittill("trigger", player); - - if (!isDefined(player) || !isDefined(player.team)) - continue; - - if(self maps\mp\gametypes\_weaponobjects::isStunned()) - continue; - - if(isDefined(self.owner) && player == self.owner) - continue; - - if(level.teamBased && self.team == player.team) - continue; - - player thread scramble_player(); - } -} - -/* - Scramble this player -*/ -scramble_player() -{ - self notify("scramble_nearby"); - self endon("scramble_nearby"); - - self.bot_scrambled = true; - wait 0.1; - - if(isDefined(self)) - self.bot_scrambled = false; -} - -/* - Watch when a player shoots -*/ -watch_shoot() -{ - self endon("disconnect"); - - self.bot_firing = false; - for(;;) - { - self waittill( "weapon_fired" ); - self thread doFiringThread(); - } -} - -/* - When a player fires -*/ -doFiringThread() -{ - self endon("disconnect"); - self endon("weapon_fired"); - - self.bot_firing = true; - wait 1; - self.bot_firing = false; -} - -/* - Watches the planes -*/ -bot_watch_planes_loop() -{ - ents = GetEntArray("script_model", "classname"); - for(i = 0; i < ents.size; i++) - { - ent = ents[i]; - - if(isDefined(ent.bot_plane)) - continue; - - if(ent.model != level.spyplanemodel) - continue; - - thread watch_plane(ent); - } -} - -/* - Watches the planes -*/ -bot_watch_planes() -{ - for(;;) - { - level waittill("uav_update"); - - bot_watch_planes_loop(); - } -} - -/* - Watches the plane -*/ -watch_plane(ent) -{ - ent.bot_plane = true; - - level.bot_planes[level.bot_planes.size] = ent; - - ent waittill_any("death", "delete", "leaving"); - - for ( entry = 0; entry < level.bot_planes.size; entry++ ) - { - if ( level.bot_planes[entry] == ent ) - { - while ( entry < level.bot_planes.size-1 ) - { - level.bot_planes[entry] = level.bot_planes[entry+1]; - entry++; - } - level.bot_planes[entry] = undefined; - break; - } - } -} - -/* - Fix xp in sd -*/ -bot_killBoost() -{ - return false; -} - -/* - Fixes sd -*/ -fixGamemodes() -{ - for(i=0;i<19;i++) - { - if(isDefined(level.bombZones) && level.gametype == "sd") - { - level.isKillBoosting = ::bot_killBoost; - for(i = 0; i < level.bombZones.size; i++) - level.bombZones[i].onUse = ::bot_onUsePlantObjectFix; - break; - } - - wait 0.05; - } -} +/* + _bot + Author: INeedGames + Date: 12/20/2020 + The entry point and manager of the bots. +*/ + +#include common_scripts\utility; +#include maps\mp\_utility; +#include maps\mp\gametypes\_hud_util; +#include maps\mp\bots\_bot_utility; + +/* + Entry point to the bots +*/ +init() +{ + level.bw_VERSION = "1.1.1"; + + level.bot_offline = false; + + if ( getDvar( "bots_main" ) == "" ) + setDvar( "bots_main", true ); + + if ( !getDvarInt( "bots_main" ) ) + return; + + if ( getDvar( "bots_main_waitForHostTime" ) == "" ) + setDvar( "bots_main_waitForHostTime", 10.0 ); //how long to wait to wait for the host player + + 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_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_codpoints" ) == "" ) // how much cod points a bot should have, -1 is around the players, 0 is all random + setDvar( "bots_loadout_codpoints", -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_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_nade" ) == "" ) //bots grenade + setDvar( "bots_play_nade", 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_move" ) == "" ) //bots move + setDvar( "bots_play_move", 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 ); + + level.bots = []; + level.bot_decoys = []; + level.bot_planes = []; + + if ( !isDefined( game["botWarfare"] ) ) + game["botWarfare"] = true; + + thread fixGamemodes(); + thread onPlayerConnect(); + thread bot_watch_planes(); + + thread handleBots(); + + thread doNonDediBots(); +} + +/* + Thread when any player connects. Starts the threads needed. +*/ +onPlayerConnect() +{ + for ( ;; ) + { + level waittill( "connected", player ); + + player thread watch_shoot(); + player thread watch_grenade(); + player thread connected(); + } +} + +/* + Starts the threads for bots. +*/ +handleBots() +{ + thread diffBots(); + thread teamBots(); + addBots(); + + while ( !level.intermission ) + wait 0.05; + + setDvar( "bots_manage_add", getBotArray().size ); +} + +/* + When a bot disconnects. +*/ +onDisconnect() +{ + self waittill( "disconnect" ); + + level.bots = array_remove( level.bots, self ); +} + +/* + Whena player connects +*/ +connected() +{ + self endon( "disconnect" ); + + if ( !self is_bot() ) + return; + + self thread maps\mp\bots\_bot_script::connected(); + + level.bots[level.bots.size] = self; + self thread onDisconnect(); + + level notify( "bot_connected", self ); +} + +/* + Handles the diff of the bots +*/ +diffBots() +{ + for ( ;; ) + { + wait 1.5; + + bot_set_difficulty( GetDvar( #"bot_difficulty" ) ); + } +} + +/* + Setup bot dvars for non dedicated clients +*/ +doNonDediBots() +{ + if ( !GetDvarInt( #"xblive_basictraining" ) ) + return; + + if ( isDefined( game[ "bots_spawned" ] ) ) + return; + + game[ "bots_spawned" ] = true; + + if ( getDvar( "bot_enemies_extra" ) == "" ) + setDvar( "bot_enemies_extra", 0 ); + + if ( getDvar( "bot_friends_extra" ) == "" ) + setDvar( "bot_friends_extra", 0 ); + + bot_friends = GetDvarInt( #"bot_friends" ); + bot_enemies = GetDvarInt( #"bot_enemies" ); + + bot_enemies += GetDvarInt( "bot_enemies_extra" ); + bot_friends += GetDvarInt( "bot_friends_extra" ); + + bot_wait_for_host(); + host = GetHostPlayer(); + + team = "allies"; + + if ( isDefined( host ) && isDefined( host.pers[ "team" ] ) && ( host.pers[ "team" ] == "allies" || host.pers[ "team" ] == "axis" ) ) + team = host.pers[ "team" ]; + + setDvar( "bots_manage_add", bot_enemies + bot_friends - 1 ); + setDvar( "bots_manage_fill", bot_enemies + bot_friends ); + setDvar( "bots_manage_fill_mode", 0 ); + setDvar( "bots_manage_fill_kick", true ); + setDvar( "bots_manage_fill_spec", false ); + + setDvar( "bots_team", "custom" ); + + if ( team == "axis" ) + setDvar( "bots_team_amount", bot_friends ); + else + setDvar( "bots_team_amount", bot_enemies ); + + setDvar( "bots_team_force", true ); + setDvar( "bots_team_mode", 0 ); +} + +/* + Sets the difficulty of the bots +*/ +bot_set_difficulty( difficulty ) +{ + if ( difficulty == "fu" ) + { + SetDvar( "sv_botMinDeathTime", "250" ); + SetDvar( "sv_botMaxDeathTime", "500" ); + SetDvar( "sv_botMinFireTime", "100" ); + SetDvar( "sv_botMaxFireTime", "300" ); + SetDvar( "sv_botYawSpeed", "14" ); + SetDvar( "sv_botYawSpeedAds", "14" ); + SetDvar( "sv_botPitchUp", "-5" ); + SetDvar( "sv_botPitchDown", "10" ); + SetDvar( "sv_botFov", "160" ); + SetDvar( "sv_botMinAdsTime", "3000" ); + SetDvar( "sv_botMaxAdsTime", "5000" ); + SetDvar( "sv_botMinCrouchTime", "100" ); + SetDvar( "sv_botMaxCrouchTime", "400" ); + SetDvar( "sv_botTargetLeadBias", "2" ); + SetDvar( "sv_botMinReactionTime", "30" ); + SetDvar( "sv_botMaxReactionTime", "100" ); + SetDvar( "sv_botStrafeChance", "1" ); + SetDvar( "sv_botMinStrafeTime", "3000" ); + SetDvar( "sv_botMaxStrafeTime", "6000" ); + SetDvar( "scr_help_dist", "512" ); + SetDvar( "sv_botAllowGrenades", "1" ); + SetDvar( "sv_botMinGrenadeTime", "1500" ); + SetDvar( "sv_botMaxGrenadeTime", "4000" ); + SetDvar( "sv_botSprintDistance", "512" ); + SetDvar( "sv_botMeleeDist", "80" ); + } + else if ( difficulty == "hard" ) + { + SetDvar( "sv_botMinDeathTime", "250" ); + SetDvar( "sv_botMaxDeathTime", "500" ); + SetDvar( "sv_botMinFireTime", "400" ); + SetDvar( "sv_botMaxFireTime", "600" ); + SetDvar( "sv_botYawSpeed", "8" ); + SetDvar( "sv_botYawSpeedAds", "10" ); + SetDvar( "sv_botPitchUp", "-5" ); + SetDvar( "sv_botPitchDown", "10" ); + SetDvar( "sv_botFov", "100" ); + SetDvar( "sv_botMinAdsTime", "3000" ); + SetDvar( "sv_botMaxAdsTime", "5000" ); + SetDvar( "sv_botMinCrouchTime", "100" ); + SetDvar( "sv_botMaxCrouchTime", "400" ); + SetDvar( "sv_botTargetLeadBias", "2" ); + SetDvar( "sv_botMinReactionTime", "400" ); + SetDvar( "sv_botMaxReactionTime", "700" ); + SetDvar( "sv_botStrafeChance", "0.9" ); + SetDvar( "sv_botMinStrafeTime", "3000" ); + SetDvar( "sv_botMaxStrafeTime", "6000" ); + SetDvar( "scr_help_dist", "384" ); + SetDvar( "sv_botAllowGrenades", "1" ); + SetDvar( "sv_botMinGrenadeTime", "1500" ); + SetDvar( "sv_botMaxGrenadeTime", "4000" ); + SetDvar( "sv_botSprintDistance", "512" ); + SetDvar( "sv_botMeleeDist", "80" ); + } + else if ( difficulty == "easy" ) + { + SetDvar( "sv_botMinDeathTime", "1000" ); + SetDvar( "sv_botMaxDeathTime", "2000" ); + SetDvar( "sv_botMinFireTime", "900" ); + SetDvar( "sv_botMaxFireTime", "1000" ); + SetDvar( "sv_botYawSpeed", "2" ); + SetDvar( "sv_botYawSpeedAds", "2.5" ); + SetDvar( "sv_botPitchUp", "-20" ); + SetDvar( "sv_botPitchDown", "40" ); + SetDvar( "sv_botFov", "50" ); + SetDvar( "sv_botMinAdsTime", "3000" ); + SetDvar( "sv_botMaxAdsTime", "5000" ); + SetDvar( "sv_botMinCrouchTime", "4000" ); + SetDvar( "sv_botMaxCrouchTime", "6000" ); + SetDvar( "sv_botTargetLeadBias", "8" ); + SetDvar( "sv_botMinReactionTime", "1200" ); + SetDvar( "sv_botMaxReactionTime", "1600" ); + SetDvar( "sv_botStrafeChance", "0.1" ); + SetDvar( "sv_botMinStrafeTime", "3000" ); + SetDvar( "sv_botMaxStrafeTime", "6000" ); + SetDvar( "scr_help_dist", "256" ); + SetDvar( "sv_botAllowGrenades", "0" ); + SetDvar( "sv_botSprintDistance", "1024" ); + SetDvar( "sv_botMeleeDist", "40" ); + } + else // 'normal' difficulty + { + SetDvar( "sv_botMinDeathTime", "500" ); + SetDvar( "sv_botMaxDeathTime", "1000" ); + SetDvar( "sv_botMinFireTime", "600" ); + SetDvar( "sv_botMaxFireTime", "800" ); + SetDvar( "sv_botYawSpeed", "4" ); + SetDvar( "sv_botYawSpeedAds", "5" ); + SetDvar( "sv_botPitchUp", "-10" ); + SetDvar( "sv_botPitchDown", "20" ); + SetDvar( "sv_botFov", "70" ); + SetDvar( "sv_botMinAdsTime", "3000" ); + SetDvar( "sv_botMaxAdsTime", "5000" ); + SetDvar( "sv_botMinCrouchTime", "2000" ); + SetDvar( "sv_botMaxCrouchTime", "4000" ); + SetDvar( "sv_botTargetLeadBias", "4" ); + SetDvar( "sv_botMinReactionTime", "800" ); + SetDvar( "sv_botMaxReactionTime", "1200" ); + SetDvar( "sv_botStrafeChance", "0.6" ); + SetDvar( "sv_botMinStrafeTime", "3000" ); + SetDvar( "sv_botMaxStrafeTime", "6000" ); + SetDvar( "scr_help_dist", "256" ); + SetDvar( "sv_botAllowGrenades", "1" ); + SetDvar( "sv_botMinGrenadeTime", "1500" ); + SetDvar( "sv_botMaxGrenadeTime", "4000" ); + SetDvar( "sv_botSprintDistance", "512" ); + SetDvar( "sv_botMeleeDist", "80" ); + difficulty = "normal"; + } + + if ( level.gameType == "oic" && difficulty == "fu" ) + { + SetDvar( "sv_botMinReactionTime", "400" ); + SetDvar( "sv_botMaxReactionTime", "500" ); + SetDvar( "sv_botMinAdsTime", "1000" ); + SetDvar( "sv_botMaxAdsTime", "2000" ); + } + + if ( level.gameType == "oic" && ( difficulty == "hard" || difficulty == "fu" ) ) + { + SetDvar( "sv_botSprintDistance", "256" ); + } + + if ( !getDvarInt( "bots_play_nade" ) ) + SetDvar( "sv_botAllowGrenades", "0" ); + + SetDvar( "bot_difficulty", difficulty ); + SetDvar( "scr_bot_difficulty", difficulty ); + SetDvar( "splitscreen_botDifficulty", difficulty ); +} + +/* + A server thread for monitoring all bot's teams for custom server settings. +*/ +teamBots_loop() +{ + teamAmount = getDvarInt( "bots_team_amount" ); + toTeam = getDvar( "bots_team" ); + + alliesbots = 0; + alliesplayers = 0; + axisbots = 0; + axisplayers = 0; + + playercount = level.players.size; + + for ( i = 0; i < playercount; i++ ) + { + 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++; + } + } + + allies = alliesbots; + axis = axisbots; + + if ( !getDvarInt( "bots_team_mode" ) ) + { + allies += alliesplayers; + axis += axisplayers; + } + + if ( toTeam != "custom" ) + { + if ( getDvarInt( "bots_team_force" ) ) + { + if ( toTeam == "autoassign" ) + { + if ( abs( axis - allies ) > 1 ) + { + toTeam = "axis"; + + if ( axis > allies ) + toTeam = "allies"; + } + } + + if ( toTeam != "autoassign" ) + { + playercount = level.players.size; + + for ( i = 0; i < playercount; i++ ) + { + 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; + } + } + } + } + else + { + playercount = level.players.size; + + for ( i = 0; i < playercount; i++ ) + { + player = level.players[i]; + + if ( !isDefined( player.pers["team"] ) ) + continue; + + if ( !player is_bot() ) + continue; + + if ( player.pers["team"] == "axis" ) + { + if ( axis > teamAmount ) + { + player thread [[level.allies]](); + break; + } + } + else + { + if ( axis < teamAmount ) + { + player thread [[level.axis]](); + break; + } + else if ( player.pers["team"] != "allies" ) + { + player thread [[level.allies]](); + break; + } + } + } + } +} + +/* + A server thread for monitoring all bot's teams for custom server settings. +*/ +teamBots() +{ + for ( ;; ) + { + wait 1.5; + teamBots_loop(); + } +} + +/* + Loop +*/ +addBots_loop() +{ + botsToAdd = GetDvarInt( "bots_manage_add" ); + + if ( botsToAdd > 0 ) + { + SetDvar( "bots_manage_add", 0 ); + + if ( botsToAdd > 64 ) + botsToAdd = 64; + + for ( ; botsToAdd > 0; botsToAdd-- ) + { + level add_bot(); + wait 0.25; + } + } + + fillMode = getDVarInt( "bots_manage_fill_mode" ); + + if ( fillMode == 2 || fillMode == 3 ) + setDvar( "bots_manage_fill", getGoodMapAmount() ); + + fillAmount = getDvarInt( "bots_manage_fill" ); + + players = 0; + bots = 0; + spec = 0; + + playercount = level.players.size; + + for ( i = 0; i < playercount; i++ ) + { + player = level.players[i]; + + if ( player isdemoclient() ) + continue; + + if ( player is_bot() ) + bots++; + else if ( !isDefined( player.pers["team"] ) || ( player.pers["team"] != "axis" && player.pers["team"] != "allies" ) ) + spec++; + else + players++; + } + + if ( fillMode == 4 ) + { + axisplayers = 0; + alliesplayers = 0; + + playercount = level.players.size; + + for ( i = 0; i < playercount; i++ ) + { + 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; + + if ( players == 0 ) + { + if ( bots < fillAmount ) + result = fillAmount - 1; + else if ( bots > fillAmount ) + result = fillAmount + 1; + else + result = fillAmount; + } + + bots = result; + } + + if ( !randomInt( 999 ) ) + { + setDvar( "testclients_doreload", true ); + wait 0.1; + setDvar( "testclients_doreload", false ); + doExtraCheck(); + } + + 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 = PickRandom( getBotArray() ); + + if ( isDefined( tempBot ) ) + kick( tempBot getEntityNumber(), "EXE_PLAYERKICKED" ); + } +} + +/* + A server thread for monitoring all bot's in game. Will add and kick bots according to server settings. + + Dedis only spawn bots when developer is not 0 + This makes the dedi unstable and can crash + + Patch the executable to skip the pregame and make it so bots can spawn + + pregame: + in the ShouldDoPregame sub: + B8 01 00 00 00: mov eax, 1 + change to: B8 00 00 00 00: mov eax, 0 + 0x4F6C77 in rektmp + 0x4598A7 in bg + + + spawnbots: + in the SV_AddTestClient sub: + 0F 85 A4 00 00 00: jnz + change to: 0F 84 A4 00 00 00: jz + 0x6B6180 in rektmp + 0x4682F0 in bg + + + allow changing g_antilag dvar: + set the byte from 0x40 to 0x00 + + 0x53B1B2 in rekt + 0x59B6F2 in bg +*/ +addBots() +{ + level endon ( "game_ended" ); + + bot_wait_for_host(); + + for ( ;; ) + { + wait 1.5; + + addBots_loop(); + } +} + +/* + Adds a bot to the game. +*/ +add_bot() +{ + bot = addtestclient(); + + if ( isdefined( bot ) ) + { + bot.pers["isBot"] = true; + bot.equipment_enabled = true; + bot.pers[ "bot_perk" ] = true; + bot.pers["isBotWarfare"] = true; + bot thread maps\mp\bots\_bot_script::added(); + } +} + +/* + Gives the bot loadout +*/ +bot_give_loadout() +{ + self maps\mp\bots\_bot_loadout::bot_give_loadout(); +} + +/* + Fired when the bot is damaged +*/ +bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHitLoc ) +{ + self maps\mp\bots\_bot_script::bot_damage_callback( eAttacker, iDamage, sMeansOfDeath, sWeapon, eInflictor, sHitLoc ); +} + +/* + Bot is idle +*/ +bot_is_idle() +{ + if ( !IsDefined( self ) ) + { + return false; + } + + if ( !IsAlive( self ) ) + { + return false; + } + + if ( !self is_bot() ) + { + return false; + } + + if ( self inLastStand() ) + { + return false; + } + + if ( self HasScriptGoal() ) + { + return false; + } + + if ( IsDefined( self GetThreat() ) ) + { + return false; + } + + if ( self IsRemoteControlling() || self.bot_lock_goal ) + { + return false; + } + + if ( self UseButtonPressed() ) + return false; + + if ( self isPlanting() ) + return false; + + if ( self isDefusing() ) + return false; + + return true; +} + +/* + Watch all players grenades +*/ +watch_grenade() +{ + self endon( "disconnect" ); + + self.bot_scrambled = false; + + for ( ;; ) + { + self waittill( "grenade_fire", g, name ); + + if ( !isDefined( g ) ) + continue; + + if ( name == "scrambler_mp" ) + { + g thread watch_scrambler(); + } + else if ( name == "nightingale_mp" ) + { + self thread watch_decoy( g ); + } + } +} + +/* + Watch the decoy grenade +*/ +watch_decoy( g ) +{ + g.team = self.team; + + level.bot_decoys[level.bot_decoys.size] = g; + + g waittill( "death" ); + + for ( entry = 0; entry < level.bot_decoys.size; entry++ ) + { + if ( level.bot_decoys[entry] == g ) + { + while ( entry < level.bot_decoys.size - 1 ) + { + level.bot_decoys[entry] = level.bot_decoys[entry + 1]; + entry++; + } + + level.bot_decoys[entry] = undefined; + break; + } + } +} + +/* + Attach a trigger to the scrambler +*/ +watch_scrambler() +{ + trig = spawn( "trigger_radius", self.origin + ( 0, 0, -1000 ), 0, 1000, 2000 ); + + self scramble_nearby( trig ); + + trig delete (); +} + +/* + Watch when players enter the scrambler trigger +*/ +scramble_nearby( trig ) +{ + self endon( "death" ); + self endon( "hacked" ); + + while ( !isDefined( self.owner ) || !isDefined( self.owner.team ) ) + wait 0.05; + + self.team = self.owner.team; + + for ( ;; ) + { + trig waittill( "trigger", player ); + + if ( !isDefined( player ) || !isDefined( player.team ) ) + continue; + + if ( self maps\mp\gametypes\_weaponobjects::isStunned() ) + continue; + + if ( isDefined( self.owner ) && player == self.owner ) + continue; + + if ( level.teamBased && self.team == player.team ) + continue; + + player thread scramble_player(); + } +} + +/* + Scramble this player +*/ +scramble_player() +{ + self notify( "scramble_nearby" ); + self endon( "scramble_nearby" ); + + self.bot_scrambled = true; + wait 0.1; + + if ( isDefined( self ) ) + self.bot_scrambled = false; +} + +/* + Watch when a player shoots +*/ +watch_shoot() +{ + self endon( "disconnect" ); + + self.bot_firing = false; + + for ( ;; ) + { + self waittill( "weapon_fired" ); + self thread doFiringThread(); + } +} + +/* + When a player fires +*/ +doFiringThread() +{ + self endon( "disconnect" ); + self endon( "weapon_fired" ); + + self.bot_firing = true; + wait 1; + self.bot_firing = false; +} + +/* + Watches the planes +*/ +bot_watch_planes_loop() +{ + ents = GetEntArray( "script_model", "classname" ); + + for ( i = 0; i < ents.size; i++ ) + { + ent = ents[i]; + + if ( isDefined( ent.bot_plane ) ) + continue; + + if ( ent.model != level.spyplanemodel ) + continue; + + thread watch_plane( ent ); + } +} + +/* + Watches the planes +*/ +bot_watch_planes() +{ + for ( ;; ) + { + level waittill( "uav_update" ); + + bot_watch_planes_loop(); + } +} + +/* + Watches the plane +*/ +watch_plane( ent ) +{ + ent.bot_plane = true; + + level.bot_planes[level.bot_planes.size] = ent; + + ent waittill_any( "death", "delete", "leaving" ); + + for ( entry = 0; entry < level.bot_planes.size; entry++ ) + { + if ( level.bot_planes[entry] == ent ) + { + while ( entry < level.bot_planes.size - 1 ) + { + level.bot_planes[entry] = level.bot_planes[entry + 1]; + entry++; + } + + level.bot_planes[entry] = undefined; + break; + } + } +} + +/* + Fix xp in sd +*/ +bot_killBoost() +{ + return false; +} + +/* + Fixes sd +*/ +fixGamemodes() +{ + for ( i = 0; i < 19; i++ ) + { + if ( isDefined( level.bombZones ) && level.gametype == "sd" ) + { + level.isKillBoosting = ::bot_killBoost; + + for ( i = 0; i < level.bombZones.size; i++ ) + level.bombZones[i].onUse = ::bot_onUsePlantObjectFix; + + break; + } + + wait 0.05; + } +}