// IW6 GSC SOURCE // Generated by https://github.com/xensik/gsc-tool main() { if ( maps\mp\_utility::is_aliens() ) return; if ( isdefined( level.createfx_enabled ) && level.createfx_enabled ) return; if ( level.script == "mp_character_room" ) return; setup_callbacks(); maps\mp\bots\_bots_personality::setup_personalities(); level.badplace_cylinder_func = ::badplace_cylinder; level.badplace_delete_func = ::badplace_delete; maps\mp\bots\_bots_ks::bot_killstreak_setup(); maps\mp\bots\_bots_loadout::init(); level thread init(); } setup_callbacks() { level.bot_funcs = []; level.bot_funcs["bots_spawn"] = ::spawn_bots; level.bot_funcs["bots_add_scavenger_bag"] = ::bot_add_scavenger_bag; level.bot_funcs["bots_add_to_level_targets"] = maps\mp\bots\_bots_util::bot_add_to_bot_level_targets; level.bot_funcs["bots_remove_from_level_targets"] = maps\mp\bots\_bots_util::bot_remove_from_bot_level_targets; level.bot_funcs["bots_make_entity_sentient"] = ::bot_make_entity_sentient; level.bot_funcs["think"] = ::bot_think; level.bot_funcs["on_killed"] = ::on_bot_killed; level.bot_funcs["should_do_killcam"] = ::bot_should_do_killcam; level.bot_funcs["get_attacker_ent"] = maps\mp\bots\_bots_util::bot_get_known_attacker; level.bot_funcs["should_pickup_weapons"] = ::bot_should_pickup_weapons; level.bot_funcs["on_damaged"] = ::bot_damage_callback; level.bot_funcs["gametype_think"] = ::default_gametype_think; level.bot_funcs["leader_dialog"] = maps\mp\bots\_bots_util::bot_leader_dialog; level.bot_funcs["player_spawned"] = ::bot_player_spawned; level.bot_funcs["should_start_cautious_approach"] = maps\mp\bots\_bots_strategy::should_start_cautious_approach_default; level.bot_funcs["know_enemies_on_start"] = ::bot_know_enemies_on_start; level.bot_funcs["bot_get_rank_xp"] = ::bot_get_rank_xp; level.bot_funcs["ai_3d_sighting_model"] = ::bot_3d_sighting_model; level.bot_funcs["dropped_weapon_think"] = ::bot_think_seek_dropped_weapons; level.bot_funcs["dropped_weapon_cancel"] = ::should_stop_seeking_weapon; level.bot_funcs["crate_can_use"] = ::crate_can_use_always; level.bot_funcs["crate_low_ammo_check"] = ::crate_low_ammo_check; level.bot_funcs["crate_should_claim"] = ::crate_should_claim; level.bot_funcs["crate_wait_use"] = ::crate_wait_use; level.bot_funcs["crate_in_range"] = ::crate_in_range; level.bot_funcs["post_teleport"] = ::bot_post_teleport; level.bot_random_path_function = []; level.bot_random_path_function["allies"] = maps\mp\bots\_bots_personality::bot_random_path_default; level.bot_random_path_function["axis"] = maps\mp\bots\_bots_personality::bot_random_path_default; level.bot_can_use_box_by_type["deployable_vest"] = ::bot_should_use_ballistic_vest_crate; level.bot_can_use_box_by_type["deployable_ammo"] = ::bot_should_use_ammo_crate; level.bot_can_use_box_by_type["scavenger_bag"] = ::bot_should_use_scavenger_bag; level.bot_can_use_box_by_type["deployable_grenades"] = ::bot_should_use_grenade_crate; level.bot_can_use_box_by_type["deployable_juicebox"] = ::bot_should_use_juicebox_crate; level.bot_pre_use_box_of_type["deployable_ammo"] = ::bot_pre_use_ammo_crate; level.bot_post_use_box_of_type["deployable_ammo"] = ::bot_post_use_ammo_crate; level.bot_find_defend_node_func["capture"] = maps\mp\bots\_bots_strategy::find_defend_node_capture; level.bot_find_defend_node_func["capture_zone"] = maps\mp\bots\_bots_strategy::find_defend_node_capture_zone; level.bot_find_defend_node_func["protect"] = maps\mp\bots\_bots_strategy::find_defend_node_protect; level.bot_find_defend_node_func["bodyguard"] = maps\mp\bots\_bots_strategy::find_defend_node_bodyguard; level.bot_find_defend_node_func["patrol"] = maps\mp\bots\_bots_strategy::find_defend_node_patrol; maps\mp\bots\_bots_gametype_war::setup_callbacks(); if ( maps\mp\_utility::bot_is_fireteam_mode() ) maps\mp\bots\_bots_fireteam::bot_fireteam_setup_callbacks(); } codecallback_leaderdialog( var_0, var_1 ) { if ( isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["leader_dialog"] ) ) self [[ level.bot_funcs["leader_dialog"] ]]( var_0, var_1 ); } init() { thread monitor_smoke_grenades(); thread bot_triggers(); initbotlevelvariables(); if ( !shouldspawnbots() ) return; refresh_existing_bots(); var_0 = botautoconnectenabled(); if ( var_0 > 0 ) { setmatchdata( "hasBots", 1 ); if ( maps\mp\_utility::bot_is_fireteam_mode() ) { level thread maps\mp\bots\_bots_fireteam::bot_fireteam_init(); level thread maps\mp\bots\_bots_fireteam_commander::init(); } else level thread bot_connect_monitor(); } } initbotlevelvariables() { if ( !isdefined( level.crateownerusetime ) ) level.crateownerusetime = 500; if ( !isdefined( level.cratenonownerusetime ) ) level.cratenonownerusetime = 3000; level.bot_out_of_combat_time = 3000; level.bot_respawn_launcher_name = "iw6_panzerfaust3"; level.bot_fallback_weapon = "iw6_knifeonly"; level.zonecount = getzonecount(); initbotmapextents(); } initbotmapextents() { if ( isdefined( level.teleportgetactivenodesfunc ) ) var_0 = [[ level.teleportgetactivenodesfunc ]](); else var_0 = getallnodes(); level.bot_map_min_x = 0; level.bot_map_max_x = 0; level.bot_map_min_y = 0; level.bot_map_max_y = 0; level.bot_map_min_z = 0; level.bot_map_max_z = 0; if ( var_0.size > 1 ) { level.bot_map_min_x = var_0[0].origin[0]; level.bot_map_max_x = var_0[0].origin[0]; level.bot_map_min_y = var_0[0].origin[1]; level.bot_map_max_y = var_0[0].origin[1]; level.bot_map_min_z = var_0[0].origin[2]; level.bot_map_max_z = var_0[0].origin[2]; for ( var_1 = 1; var_1 < var_0.size; var_1++ ) { var_2 = var_0[var_1].origin; if ( var_2[0] < level.bot_map_min_x ) level.bot_map_min_x = var_2[0]; if ( var_2[0] > level.bot_map_max_x ) level.bot_map_max_x = var_2[0]; if ( var_2[1] < level.bot_map_min_y ) level.bot_map_min_y = var_2[1]; if ( var_2[1] > level.bot_map_max_y ) level.bot_map_max_y = var_2[1]; if ( var_2[2] < level.bot_map_min_z ) level.bot_map_min_z = var_2[2]; if ( var_2[2] > level.bot_map_max_z ) level.bot_map_max_z = var_2[2]; } } level.bot_map_center = ( ( level.bot_map_min_x + level.bot_map_max_x ) / 2, ( level.bot_map_min_y + level.bot_map_max_y ) / 2, ( level.bot_map_min_z + level.bot_map_max_z ) / 2 ); level.bot_variables_initialized = 1; } bot_post_teleport() { level.bot_variables_initialized = undefined; level.bot_initialized_remote_vehicles = undefined; initbotmapextents(); maps\mp\bots\_bots_ks_remote_vehicle::remote_vehicle_setup(); } shouldspawnbots() { return 1; } refresh_existing_bots() { wait 1; foreach ( var_1 in level.players ) { if ( isbot( var_1 ) ) { var_1.equipment_enabled = 1; var_1.bot_team = var_1.team; var_1.bot_spawned_before = 1; var_1 thread [[ level.bot_funcs["think"] ]](); } } } bot_player_spawned() { bot_set_loadout_class(); if ( isdefined( self.prev_personality ) ) { maps\mp\bots\_bots_util::bot_set_personality( self.prev_personality ); self.prev_personality = undefined; } } bot_set_loadout_class() { if ( !isdefined( self.bot_class ) ) { if ( !bot_gametype_chooses_class() ) { while ( !isdefined( level.bot_loadouts_initialized ) ) wait 0.05; if ( isdefined( self.override_class_function ) ) self.bot_class = [[ self.override_class_function ]](); else self.bot_class = maps\mp\bots\_bots_personality::bot_setup_callback_class(); } else self.bot_class = self.class; } } watch_players_connecting() { for (;;) { level waittill( "connected", var_0 ); if ( !isai( var_0 ) && level.players.size > 0 ) { level.players_waiting_to_join = common_scripts\utility::array_add( level.players_waiting_to_join, var_0 ); childthread bots_notify_on_spawn( var_0 ); childthread bots_notify_on_disconnect( var_0 ); childthread bots_remove_from_array_on_notify( var_0 ); } } } bots_notify_on_spawn( var_0 ) { var_0 endon( "bots_human_disconnected" ); while ( !common_scripts\utility::array_contains( level.players, var_0 ) ) wait 0.05; var_0 notify( "bots_human_spawned" ); } bots_notify_on_disconnect( var_0 ) { var_0 endon( "bots_human_spawned" ); var_0 waittill( "disconnect" ); var_0 notify( "bots_human_disconnected" ); } bots_remove_from_array_on_notify( var_0 ) { var_0 common_scripts\utility::waittill_any( "bots_human_spawned", "bots_human_disconnected" ); level.players_waiting_to_join = common_scripts\utility::array_remove( level.players_waiting_to_join, var_0 ); } monitor_pause_spawning() { level.players_waiting_to_join = []; childthread watch_players_connecting(); for (;;) { if ( level.players_waiting_to_join.size > 0 ) level.pausing_bot_connect_monitor = 1; else level.pausing_bot_connect_monitor = 0; wait 0.5; } } bot_can_join_team( var_0 ) { if ( maps\mp\_utility::matchmakinggame() ) return 1; if ( getdvar( "squad_vs_squad" ) == "1" ) return 1; if ( !level.teambased ) return 1; if ( maps\mp\gametypes\_teams::getjointeampermissions( var_0 ) ) return 1; return 0; } bot_connect_monitor( var_0, var_1 ) { level endon( "game_ended" ); self notify( "bot_connect_monitor" ); self endon( "bot_connect_monitor" ); level.pausing_bot_connect_monitor = 0; childthread monitor_pause_spawning(); maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( 0.5 ); var_2 = 1.5; if ( !isdefined( level.bot_cm_spawned_bots ) ) level.bot_cm_spawned_bots = 0; if ( !isdefined( level.bot_cm_waited_players_time ) ) level.bot_cm_waited_players_time = 0; if ( !isdefined( level.bot_cm_human_picked ) ) level.bot_cm_human_picked = 0; if ( getdvar( "squad_vs_squad" ) == "1" ) { while ( !( isdefined( level.squad_vs_squad_allies_client ) && isdefined( level.squad_vs_squad_axis_client ) ) ) wait 0.05; wait 2.0; } if ( getdvar( "squad_match" ) == "1" ) { while ( !isdefined( level.squad_match_client ) ) wait 0.05; wait 2.0; } if ( getdvar( "squad_use_hosts_squad" ) == "1" ) { while ( !isdefined( level.wargame_client ) ) wait 0.05; wait 2.0; } for (;;) { if ( level.pausing_bot_connect_monitor ) { maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_2 ); continue; } var_3 = isdefined( level.bots_ignore_team_balance ) || !level.teambased; var_4 = botgetteamlimit( 0 ); var_5 = botgetteamlimit( 1 ); var_6 = botgetteamdifficulty( 0 ); var_7 = botgetteamdifficulty( 1 ); var_8 = "allies"; var_9 = "axis"; var_10 = bot_client_counts(); var_11 = cat_array_get( var_10, "humans" ); if ( var_11 > 1 ) { var_12 = bot_get_host_team(); if ( !maps\mp\_utility::matchmakinggame() && isdefined( var_12 ) && var_12 != "spectator" ) { var_8 = var_12; var_9 = maps\mp\_utility::getotherteam( var_12 ); } else { var_13 = cat_array_get( var_10, "humans_allies" ); var_14 = cat_array_get( var_10, "humans_axis" ); if ( var_14 > var_13 ) { var_8 = "axis"; var_9 = "allies"; } } } else { var_15 = get_human_player(); if ( isdefined( var_15 ) ) { var_16 = var_15 bot_get_player_team(); if ( isdefined( var_16 ) && var_16 != "spectator" ) { var_8 = var_16; var_9 = maps\mp\_utility::getotherteam( var_16 ); } } } var_17 = maps\mp\bots\_bots_util::bot_get_team_limit(); var_18 = maps\mp\bots\_bots_util::bot_get_team_limit(); if ( var_17 + var_18 < maps\mp\bots\_bots_util::bot_get_client_limit() ) { if ( var_17 < var_4 ) var_17++; else if ( var_18 < var_5 ) var_18++; } var_19 = cat_array_get( var_10, "humans_" + var_8 ); var_20 = cat_array_get( var_10, "humans_" + var_9 ); var_21 = var_19 + var_20; var_22 = cat_array_get( var_10, "spectator" ); var_23 = 0; for ( var_24 = 0; var_22 > 0; var_22-- ) { var_25 = var_19 + var_23 + 1 <= var_17; var_26 = var_20 + var_24 + 1 <= var_18; if ( var_25 && !var_26 ) { var_23++; continue; } if ( !var_25 && var_26 ) { var_24++; continue; } if ( var_25 && var_26 ) { if ( var_22 % 2 == 1 ) { var_23++; continue; } var_24++; } } var_27 = cat_array_get( var_10, "bots_" + var_8 ); var_28 = cat_array_get( var_10, "bots_" + var_9 ); var_29 = var_27 + var_28; if ( var_29 > 0 ) level.bot_cm_spawned_bots = 1; var_30 = 0; if ( !level.bot_cm_human_picked ) { var_30 = !bot_get_human_picked_team(); if ( !var_30 ) level.bot_cm_human_picked = 1; } if ( var_30 ) { var_31 = !getdvarint( "systemlink" ) && !getdvarint( "onlinegame" ); var_32 = !var_3 && var_5 != var_4 && !level.bot_cm_spawned_bots && ( level.bot_cm_waited_players_time < 10 || !maps\mp\_utility::gameflag( "prematch_done" ) ); if ( var_31 || var_32 ) { level.bot_cm_waited_players_time = level.bot_cm_waited_players_time + var_2; maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_2 ); continue; } } var_33 = int( min( var_17 - var_19 - var_23, var_4 ) ); var_34 = int( min( var_18 - var_20 - var_24, var_5 ) ); var_35 = 1; var_36 = var_33 + var_34 + var_11; var_37 = var_4 + var_5 + var_11; for ( var_38 = [ -1, -1 ]; var_36 < maps\mp\bots\_bots_util::bot_get_client_limit() && var_36 < var_37; var_35 = !var_35 ) { if ( var_35 && var_33 < var_4 && bot_can_join_team( var_8 ) ) var_33++; else if ( !var_35 && var_34 < var_5 && bot_can_join_team( var_9 ) ) var_34++; var_36 = var_33 + var_34 + var_11; if ( var_38[var_35] == var_36 ) break; var_38[var_35] = var_36; } if ( var_4 == var_5 && !var_3 && var_23 == 1 && var_24 == 0 && var_34 > 0 ) { if ( !isdefined( level.bot_prematchdonetime ) && maps\mp\_utility::gameflag( "prematch_done" ) ) level.bot_prematchdonetime = gettime(); if ( var_30 && ( !isdefined( level.bot_prematchdonetime ) || gettime() - level.bot_prematchdonetime < 10000 ) ) var_34--; } var_39 = var_33 - var_27; var_40 = var_34 - var_28; var_41 = 1; if ( var_3 ) { var_42 = var_17 + var_18; var_43 = var_4 + var_5; var_44 = var_19 + var_20; var_45 = var_27 + var_28; var_46 = int( min( var_42 - var_44, var_43 ) ); var_47 = var_46 - var_45; if ( var_47 == 0 ) var_41 = 0; else if ( var_47 > 0 ) { var_39 = int( var_47 / 2 ) + var_47 % 2; var_40 = int( var_47 / 2 ); } else if ( var_47 < 0 ) { var_48 = var_47 * -1; var_39 = -1 * int( min( var_48, var_27 ) ); var_40 = -1 * ( var_48 + var_39 ); } } else if ( !maps\mp\_utility::matchmakinggame() && ( var_39 * var_40 < 0 && maps\mp\_utility::gameflag( "prematch_done" ) && !isdefined( level.bots_disable_team_switching ) ) ) { var_49 = int( min( abs( var_39 ), abs( var_40 ) ) ); if ( var_39 > 0 ) move_bots_from_team_to_team( var_49, var_9, var_8, var_6 ); else if ( var_40 > 0 ) move_bots_from_team_to_team( var_49, var_8, var_9, var_7 ); var_41 = 0; } if ( var_41 ) { if ( var_40 < 0 ) drop_bots( var_40 * -1, var_9 ); if ( var_39 < 0 ) drop_bots( var_39 * -1, var_8 ); if ( var_40 > 0 ) level thread spawn_bots( var_40, var_9, undefined, undefined, "spawned_enemies", var_7 ); if ( var_39 > 0 ) level thread spawn_bots( var_39, var_8, undefined, undefined, "spawned_allies", var_6 ); if ( var_40 > 0 && var_39 > 0 ) level common_scripts\utility::waittill_multiple( "spawned_enemies", "spawned_allies" ); else if ( var_40 > 0 ) level waittill( "spawned_enemies" ); else if ( var_39 > 0 ) level waittill( "spawned_allies" ); } if ( var_7 != var_6 ) { bots_update_difficulty( var_9, var_7 ); bots_update_difficulty( var_8, var_6 ); } maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( var_2 ); } } bot_get_player_team() { if ( isdefined( self.team ) ) return self.team; if ( isdefined( self.pers["team"] ) ) return self.pers["team"]; return undefined; } bot_get_host_team() { foreach ( var_1 in level.players ) { if ( !isai( var_1 ) && var_1 ishost() ) return var_1 bot_get_player_team(); } return "spectator"; } bot_get_human_picked_team() { var_0 = 0; var_1 = 0; var_2 = 0; foreach ( var_4 in level.players ) { if ( !isai( var_4 ) ) { if ( var_4 ishost() ) var_0 = 1; if ( player_picked_team( var_4 ) ) { var_1 = 1; if ( var_4 ishost() ) var_2 = 1; } } } return var_2 || var_1 && !var_0; } player_picked_team( var_0 ) { if ( isdefined( var_0.team ) && var_0.team != "spectator" ) return 1; if ( isdefined( var_0.spectating_actively ) && var_0.spectating_actively ) return 1; if ( var_0 ismlgspectator() && isdefined( var_0.team ) && var_0.team == "spectator" ) return 1; return 0; } bot_client_counts() { var_0 = []; for ( var_1 = 0; var_1 < level.players.size; var_1++ ) { var_2 = level.players[var_1]; if ( isdefined( var_2 ) && isdefined( var_2.team ) ) { var_0 = cat_array_add( var_0, "all" ); var_0 = cat_array_add( var_0, var_2.team ); if ( isbot( var_2 ) ) { var_0 = cat_array_add( var_0, "bots" ); var_0 = cat_array_add( var_0, "bots_" + var_2.team ); continue; } var_0 = cat_array_add( var_0, "humans" ); var_0 = cat_array_add( var_0, "humans_" + var_2.team ); } } return var_0; } cat_array_add( var_0, var_1 ) { if ( !isdefined( var_0 ) ) var_0 = []; if ( !isdefined( var_0[var_1] ) ) var_0[var_1] = 0; var_0[var_1] = var_0[var_1] + 1; return var_0; } cat_array_get( var_0, var_1 ) { if ( !isdefined( var_0 ) ) return 0; if ( !isdefined( var_0[var_1] ) ) return 0; return var_0[var_1]; } move_bots_from_team_to_team( var_0, var_1, var_2, var_3 ) { foreach ( var_5 in level.players ) { if ( !isdefined( var_5.team ) ) continue; if ( isdefined( var_5.connected ) && var_5.connected && isbot( var_5 ) && var_5.team == var_1 ) { var_5.bot_team = var_2; if ( isdefined( var_3 ) ) var_5 maps\mp\bots\_bots_util::bot_set_difficulty( var_3 ); var_5 notify( "luinotifyserver", "team_select", bot_lui_convert_team_to_int( var_2 ) ); wait 0.05; var_5 notify( "luinotifyserver", "class_select", var_5.bot_class ); var_0--; if ( var_0 <= 0 ) break; else wait 0.1; } } } bots_update_difficulty( var_0, var_1 ) { foreach ( var_3 in level.players ) { if ( !isdefined( var_3.team ) ) continue; if ( isdefined( var_3.connected ) && var_3.connected && isbot( var_3 ) && var_3.team == var_0 ) { if ( var_1 != var_3 botgetdifficulty() ) var_3 maps\mp\bots\_bots_util::bot_set_difficulty( var_1 ); } } } bot_drop() { kick( self.entity_number, "EXE_PLAYERKICKED_BOT_BALANCE" ); wait 0.1; } drop_bots( var_0, var_1 ) { var_2 = []; foreach ( var_4 in level.players ) { if ( isdefined( var_4.connected ) && var_4.connected && isbot( var_4 ) && ( !isdefined( var_1 ) || isdefined( var_4.team ) && var_4.team == var_1 ) ) var_2[var_2.size] = var_4; } for ( var_6 = var_2.size - 1; var_6 >= 0; var_6-- ) { if ( var_0 <= 0 ) break; if ( !maps\mp\_utility::isreallyalive( var_2[var_6] ) ) { var_2[var_6] bot_drop(); var_2 = common_scripts\utility::array_remove( var_2, var_2[var_6] ); var_0--; } } for ( var_6 = var_2.size - 1; var_6 >= 0; var_6-- ) { if ( var_0 <= 0 ) break; var_2[var_6] bot_drop(); var_0--; } } bot_lui_convert_team_to_int( var_0 ) { if ( var_0 == "axis" ) return 0; else if ( var_0 == "allies" ) return 1; else if ( var_0 == "autoassign" || var_0 == "random" ) return 2; else return 3; } spawn_bot_latent( var_0, var_1, var_2 ) { var_3 = gettime() + 60000; while ( !self canspawntestclient() ) { if ( gettime() >= var_3 ) { kick( self.entity_number, "EXE_PLAYERKICKED_BOT_BALANCE" ); var_2.abort = 1; return; } wait 0.05; if ( !isdefined( self ) ) { var_2.abort = 1; return; } } maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( randomfloatrange( 0.25, 2.0 ) ); if ( !isdefined( self ) ) { var_2.abort = 1; return; } self spawntestclient(); self.pers["isBot"] = 1; self.equipment_enabled = 1; self.bot_team = var_0; if ( isdefined( var_2.difficulty ) ) maps\mp\bots\_bots_util::bot_set_difficulty( var_2.difficulty ); if ( isdefined( var_1 ) ) self [[ var_1 ]](); self thread [[ level.bot_funcs["think"] ]](); var_2.ready = 1; } find_squad_member_index( var_0, var_1 ) { var_2 = var_0 getrankedplayerdata( "activeSquadMember" ); var_3 = 0; var_4 = 0; while ( var_4 < 10 ) { var_3 = 0; var_5 = var_0 getrankedplayerdata( "squadHQ", "aiSquadMembers", var_4 ); if ( var_5 == var_2 ) { var_4++; continue; } if ( !isdefined( level.human_team_bot_added ) || !isdefined( level.human_team_bot_added[var_5] ) || level.human_team_bot_added[var_5] == 0 ) return var_5; var_4++; } return -1; } spawn_bots( var_0, var_1, var_2, var_3, var_4, var_5 ) { var_6 = gettime() + 10000; var_7 = []; var_8 = var_7.size; while ( level.players.size < maps\mp\bots\_bots_util::bot_get_client_limit() && var_7.size < var_0 && gettime() < var_6 ) { maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( 0.05 ); var_9 = undefined; if ( getdvar( "squad_vs_squad" ) == "1" ) { var_10 = level.squad_vs_squad_axis_client; if ( var_1 == "allies" ) var_10 = level.squad_vs_squad_allies_client; if ( isdefined( var_10 ) ) { var_11 = var_8; var_12 = var_10 getrankedplayerdata( "activeSquadMember" ); var_13 = 0; var_14 = 0; for ( var_15 = 0; var_15 < maps\mp\bots\_bots_util::bot_get_team_limit(); var_15++ ) { var_14 = var_10 getrankedplayerdata( "squadHQ", "aiSquadMembers", var_15 ); if ( var_14 == var_12 ) continue; if ( var_11 == var_13 ) break; var_13++; } var_16 = var_10 getrankedplayerdata( "squadMembers", var_14, "name" ); var_17 = var_10 getrankedplayerdata( "squadMembers", var_14, "head" ); var_18 = var_10 getrankedplayerdata( "squadMembers", var_14, "body" ); var_19 = var_10 getrankedplayerdata( "squadMembers", var_14, "helmet" ); var_9 = addbot( var_16, var_17, var_18, var_19 ); if ( isdefined( var_9 ) ) var_9.pers["squadSlot"] = var_14; } else if ( !isdefined( level.squad_vs_squad_has_forfeited ) ) { if ( isdefined( level.squad_vs_squad_axis_client ) ) { level.finalkillcam_winner = "axis"; thread maps\mp\gametypes\_gamelogic::endgame( "axis", game["end_reason"]["allies_forfeited"] ); } else { level.finalkillcam_winner = "allies"; thread maps\mp\gametypes\_gamelogic::endgame( "allies", game["end_reason"]["axis_forfeited"] ); } level.squad_vs_squad_has_forfeited = 1; } } else if ( getdvar( "squad_use_hosts_squad" ) == "1" ) { if ( level.wargame_client.team == var_1 ) { if ( maps\mp\_utility::matchmakinggame() ) { var_14 = find_squad_member_index( level.wargame_client, var_1 ); var_16 = level.wargame_client getrankedplayerdata( "squadMembers", var_14, "name" ); var_17 = level.wargame_client getrankedplayerdata( "squadMembers", var_14, "head" ); var_18 = level.wargame_client getrankedplayerdata( "squadMembers", var_14, "body" ); var_19 = level.wargame_client getrankedplayerdata( "squadMembers", var_14, "helmet" ); var_9 = addbot( var_16, var_17, var_18, var_19 ); if ( isdefined( var_9 ) ) { level.human_team_bot_added[var_14] = 1; var_9.pers["squadSlot"] = var_14; } } else { var_11 = var_8; var_12 = level.wargame_client getprivateplayerdata( "privateMatchActiveSquadMember" ); var_13 = 0; var_14 = 0; for ( var_15 = 0; var_15 < maps\mp\bots\_bots_util::bot_get_team_limit(); var_15++ ) { var_14 = var_15; if ( var_15 == var_12 ) continue; if ( var_11 == var_13 ) break; var_13++; } var_16 = level.wargame_client getprivateplayerdata( "privateMatchSquadMembers", var_14, "name" ); var_17 = level.wargame_client getprivateplayerdata( "privateMatchSquadMembers", var_14, "head" ); var_18 = level.wargame_client getprivateplayerdata( "privateMatchSquadMembers", var_14, "body" ); var_19 = level.wargame_client getprivateplayerdata( "privateMatchSquadMembers", var_14, "helmet" ); var_9 = addbot( var_16, var_17, var_18, var_19 ); if ( isdefined( var_9 ) ) var_9.pers["squadSlot"] = var_14; } } else var_9 = addbot( "", 0, 0, 0 ); } else if ( getdvar( "squad_match" ) == "1" ) { if ( var_1 == "axis" ) { var_14 = getenemysquaddata( "squadHQ", "aiSquadMembers", var_8 ); var_16 = getenemysquaddata( "squadMembers", var_14, "name" ); var_17 = getenemysquaddata( "squadMembers", var_14, "head" ); var_18 = getenemysquaddata( "squadMembers", var_14, "body" ); var_19 = getenemysquaddata( "squadMembers", var_14, "helmet" ); var_9 = addbot( var_16, var_17, var_18, var_19 ); if ( isdefined( var_9 ) ) var_9.pers["squadSlot"] = var_14; } else { var_14 = find_squad_member_index( level.squad_match_client, var_1 ); if ( var_14 > -1 ) { var_16 = level.squad_match_client getrankedplayerdata( "squadMembers", var_14, "name" ); var_17 = level.squad_match_client getrankedplayerdata( "squadMembers", var_14, "head" ); var_18 = level.squad_match_client getrankedplayerdata( "squadMembers", var_14, "body" ); var_19 = level.squad_match_client getrankedplayerdata( "squadMembers", var_14, "helmet" ); var_9 = addbot( var_16, var_17, var_18, var_19 ); if ( isdefined( var_9 ) ) { level.human_team_bot_added[var_14] = 1; var_9.pers["squadSlot"] = var_14; } } } } else var_9 = addbot( "", 0, 0, 0 ); if ( !isdefined( var_9 ) ) { if ( isdefined( var_3 ) && var_3 ) { if ( isdefined( var_4 ) ) self notify( var_4 ); return; } maps\mp\gametypes\_hostmigration::waitlongdurationwithhostmigrationpause( 1 ); continue; } else { var_20 = spawnstruct(); var_20.bot = var_9; var_20.ready = 0; var_20.abort = 0; var_20.index = var_8; var_20.difficulty = var_5; var_7[var_7.size] = var_20; var_20.bot thread spawn_bot_latent( var_1, var_2, var_20 ); var_8++; } } var_21 = 0; var_6 = gettime() + 60000; while ( var_21 < var_7.size && gettime() < var_6 ) { var_21 = 0; foreach ( var_20 in var_7 ) { if ( var_20.ready || var_20.abort ) var_21++; } wait 0.05; } if ( isdefined( var_4 ) ) self notify( var_4 ); } bot_gametype_chooses_team() { if ( !level.teambased ) return 1; if ( isdefined( level.bots_gametype_handles_team_choice ) && level.bots_gametype_handles_team_choice ) return 1; return 0; } bot_gametype_chooses_class() { return isdefined( level.bots_gametype_handles_class_choice ) && level.bots_gametype_handles_class_choice; } bot_think() { self notify( "bot_think" ); self endon( "bot_think" ); self endon( "disconnect" ); while ( !isdefined( self.pers["team"] ) ) wait 0.05; level.hasbots = 1; if ( bot_gametype_chooses_team() ) self.bot_team = self.pers["team"]; var_0 = self.bot_team; if ( !isdefined( var_0 ) ) var_0 = self.pers["team"]; maps\mp\bots\_bots_ks::bot_killstreak_setup(); self.entity_number = self getentitynumber(); var_1 = 0; if ( !isdefined( self.bot_spawned_before ) ) { var_1 = 1; self.bot_spawned_before = 1; if ( !bot_gametype_chooses_team() ) { self notify( "luinotifyserver", "team_select", bot_lui_convert_team_to_int( var_0 ) ); wait 0.5; if ( self.pers["team"] == "spectator" ) { bot_drop(); return; } } } for (;;) { maps\mp\bots\_bots_util::bot_set_difficulty( self botgetdifficulty() ); var_2 = self botgetdifficultysetting( "advancedPersonality" ); if ( var_1 && isdefined( var_2 ) && var_2 != 0 ) maps\mp\bots\_bots_personality::bot_balance_personality(); maps\mp\bots\_bots_personality::bot_assign_personality_functions(); if ( var_1 ) { bot_set_loadout_class(); if ( !bot_gametype_chooses_class() ) self notify( "luinotifyserver", "class_select", self.bot_class ); if ( self.health == 0 ) self waittill( "spawned_player" ); if ( isdefined( level.bot_funcs ) && isdefined( level.bot_funcs["know_enemies_on_start"] ) ) self thread [[ level.bot_funcs["know_enemies_on_start"] ]](); var_1 = 0; } bot_restart_think_threads(); wait 0.1; self waittill( "death" ); respawn_watcher(); self waittill( "spawned_player" ); } } respawn_watcher() { self endon( "started_spawnPlayer" ); while ( !self.waitingtospawn ) wait 0.05; if ( maps\mp\gametypes\_playerlogic::needsbuttontorespawn() ) { while ( self.waitingtospawn ) { if ( self.sessionstate == "spectator" ) { if ( getdvarint( "numlives" ) == 0 || self.pers["lives"] > 0 ) self botpressbutton( "use", 0.5 ); } wait 1.0; } } } bot_get_rank_xp() { if ( maps\mp\_utility::bot_israndom() == 0 ) { if ( !isdefined( self.pers["rankxp"] ) ) self.pers["rankxp"] = 0; return self.pers["rankxp"]; } var_0 = self botgetdifficulty(); var_1 = "bot_rank_" + var_0; if ( isdefined( self.pers[var_1] ) && self.pers[var_1] > 0 ) return self.pers[var_1]; var_2 = bot_random_ranks_for_difficulty( var_0 ); var_3 = var_2["rank"]; var_4 = var_2["prestige"]; var_5 = maps\mp\gametypes\_rank::getrankinfominxp( var_3 ); var_6 = var_5 + maps\mp\gametypes\_rank::getrankinfoxpamt( var_3 ); var_7 = randomintrange( var_5, var_6 + 1 ); self.pers[var_1] = var_7; return var_7; } bot_3d_sighting_model( var_0 ) { thread bot_3d_sighting_model_thread( var_0 ); } bot_3d_sighting_model_thread( var_0 ) { var_0 endon( "disconnect" ); self endon( "disconnect" ); level endon( "game_ended" ); for (;;) { if ( isalive( self ) && !self botcanseeentity( var_0 ) && common_scripts\utility::within_fov( self.origin, self.angles, var_0.origin, self botgetfovdot() ) ) self botgetimperfectenemyinfo( var_0, var_0.origin ); wait 0.1; } } bot_random_ranks_for_difficulty( var_0 ) { var_1 = []; var_1["rank"] = 0; var_1["prestige"] = 0; if ( var_0 == "default" ) return var_1; if ( !isdefined( level.bot_rnd_rank ) ) { level.bot_rnd_rank = []; level.bot_rnd_rank["recruit"][0] = 0; level.bot_rnd_rank["recruit"][1] = 7; level.bot_rnd_rank["regular"][0] = 9; level.bot_rnd_rank["regular"][1] = 37; level.bot_rnd_rank["hardened"][0] = 39; level.bot_rnd_rank["hardened"][1] = 57; level.bot_rnd_rank["veteran"][0] = 59; level.bot_rnd_rank["veteran"][1] = 59; } if ( !isdefined( level.bot_rnd_prestige ) ) { level.bot_rnd_prestige = []; level.bot_rnd_prestige["recruit"][0] = 0; level.bot_rnd_prestige["recruit"][1] = 0; level.bot_rnd_prestige["regular"][0] = 0; level.bot_rnd_prestige["regular"][1] = 0; level.bot_rnd_prestige["hardened"][0] = 0; level.bot_rnd_prestige["hardened"][1] = 0; level.bot_rnd_prestige["veteran"][0] = 0; level.bot_rnd_prestige["veteran"][1] = 9; } if ( isdefined( level.bot_rnd_rank[var_0][0] ) && isdefined( level.bot_rnd_rank[var_0][1] ) ) var_1["rank"] = randomintrange( level.bot_rnd_rank[var_0][0], level.bot_rnd_rank[var_0][1] + 1 ); if ( isdefined( level.bot_rnd_prestige[var_0][0] ) && isdefined( level.bot_rnd_prestige[var_0][1] ) ) var_1["prestige"] = randomintrange( level.bot_rnd_prestige[var_0][0], level.bot_rnd_prestige[var_0][1] + 1 ); return var_1; } crate_can_use_always( var_0 ) { if ( isagent( self ) && !isdefined( var_0.boxtype ) ) return 0; return 1; } get_human_player() { var_0 = undefined; var_1 = getentarray( "player", "classname" ); if ( isdefined( var_1 ) ) { for ( var_2 = 0; var_2 < var_1.size; var_2++ ) { if ( isdefined( var_1[var_2] ) && isdefined( var_1[var_2].connected ) && var_1[var_2].connected && !isai( var_1[var_2] ) && ( !isdefined( var_0 ) || var_0.team == "spectator" ) ) var_0 = var_1[var_2]; } } return var_0; } bot_damage_callback( var_0, var_1, var_2, var_3, var_4, var_5 ) { if ( !isdefined( self ) || !isalive( self ) ) return; if ( var_2 == "MOD_FALLING" || var_2 == "MOD_SUICIDE" ) return; if ( var_1 <= 0 ) return; if ( !isdefined( var_4 ) ) { if ( !isdefined( var_0 ) ) return; var_4 = var_0; } if ( isdefined( var_4 ) ) { if ( level.teambased ) { if ( isdefined( var_4.team ) && var_4.team == self.team ) return; else if ( isdefined( var_0 ) && isdefined( var_0.team ) && var_0.team == self.team ) return; } var_6 = maps\mp\bots\_bots_util::bot_get_known_attacker( var_0, var_4 ); if ( isdefined( var_6 ) ) self botsetattacker( var_6 ); } } on_bot_killed( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8, var_9 ) { self botclearscriptenemy(); self botclearscriptgoal(); var_10 = maps\mp\bots\_bots_util::bot_get_known_attacker( var_1, var_0 ); if ( !maps\mp\_utility::bot_is_fireteam_mode() && getdvar( "squad_match" ) != "1" && getdvar( "squad_vs_squad" ) != "1" && isdefined( var_10 ) && var_10.classname == "script_vehicle" && isdefined( var_10.helitype ) ) { var_11 = self botgetdifficultysetting( "launcherRespawnChance" ); if ( randomfloat( 1.0 ) < var_11 ) self.respawn_with_launcher = 1; } } bot_should_do_killcam() { if ( maps\mp\_utility::bot_is_fireteam_mode() ) return 0; var_0 = 0.0; var_1 = self botgetdifficulty(); if ( var_1 == "recruit" ) var_0 = 0.1; else if ( var_1 == "regular" ) var_0 = 0.4; else if ( var_1 == "hardened" ) var_0 = 0.7; else if ( var_1 == "veteran" ) var_0 = 1.0; return randomfloat( 1.0 ) < 1.0 - var_0; } bot_should_pickup_weapons() { if ( maps\mp\_utility::isjuggernaut() ) return 0; return 1; } bot_restart_think_threads() { thread bot_think_watch_enemy(); thread maps\mp\bots\_bots_strategy::bot_think_tactical_goals(); self thread [[ level.bot_funcs["dropped_weapon_think"] ]](); thread bot_think_level_actions(); thread bot_think_crate(); thread bot_think_crate_blocking_path(); thread maps\mp\bots\_bots_ks::bot_think_killstreak(); thread maps\mp\bots\_bots_ks::bot_think_watch_aerial_killstreak(); thread bot_think_gametype(); } bot_think_watch_enemy( var_0 ) { var_1 = "spawned_player"; if ( isdefined( var_0 ) && var_0 ) var_1 = "death"; self notify( "bot_think_watch_enemy" ); self endon( "bot_think_watch_enemy" ); self endon( var_1 ); self endon( "disconnect" ); level endon( "game_ended" ); self.last_enemy_sight_time = gettime(); for (;;) { if ( isdefined( self.enemy ) ) { if ( self botcanseeentity( self.enemy ) ) self.last_enemy_sight_time = gettime(); } wait 0.05; } } bot_think_seek_dropped_weapons() { self notify( "bot_think_seek_dropped_weapons" ); self endon( "bot_think_seek_dropped_weapons" ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); var_0 = "throwingknife_mp"; var_1 = "throwingknifejugg_mp"; for (;;) { var_2 = 0; if ( maps\mp\bots\_bots_util::bot_out_of_ammo() && self [[ level.bot_funcs["should_pickup_weapons"] ]]() && !maps\mp\bots\_bots_util::bot_is_remote_or_linked() ) { var_3 = getentarray( "dropped_weapon", "targetname" ); var_4 = common_scripts\utility::get_array_of_closest( self.origin, var_3 ); if ( var_4.size > 0 ) { var_5 = var_4[0]; bot_seek_dropped_weapon( var_5 ); } } if ( !maps\mp\bots\_bots_util::bot_in_combat() && !maps\mp\bots\_bots_util::bot_is_remote_or_linked() && self botgetdifficultysetting( "strategyLevel" ) > 0 ) { var_6 = self hasweapon( var_0 ); var_7 = self hasweapon( var_1 ); var_8 = var_6 && self getammocount( var_0 ) == 0 || var_7 && self getammocount( var_1 ) == 0; if ( var_8 ) { if ( isdefined( self.going_for_knife ) ) { wait 5.0; continue; } var_9 = getentarray( "dropped_knife", "targetname" ); var_10 = common_scripts\utility::get_array_of_closest( self.origin, var_9 ); foreach ( var_12 in var_10 ) { if ( !isdefined( var_12 ) ) continue; if ( !isdefined( var_12.calculated_closest_point ) ) { var_13 = maps\mp\bots\_bots_util::bot_queued_process( "BotGetClosestNavigablePoint", maps\mp\bots\_bots_util::func_bot_get_closest_navigable_point, var_12.origin, 32, self ); if ( isdefined( var_12 ) ) { var_12.closest_point_on_grid = var_13; var_12.calculated_closest_point = 1; } else continue; } if ( isdefined( var_12.closest_point_on_grid ) ) { self.going_for_knife = 1; bot_seek_dropped_weapon( var_12 ); } } } else if ( var_6 || var_7 ) self.going_for_knife = undefined; } wait( randomfloatrange( 0.25, 0.75 ) ); } } bot_seek_dropped_weapon( var_0 ) { if ( maps\mp\bots\_bots_strategy::bot_has_tactical_goal( "seek_dropped_weapon", var_0 ) == 0 ) { var_1 = undefined; if ( var_0.targetname == "dropped_weapon" ) { var_2 = 1; var_3 = self getweaponslistprimaries(); foreach ( var_5 in var_3 ) { if ( var_0.model == getweaponmodel( var_5 ) ) var_2 = 0; } if ( var_2 ) var_1 = ::bot_pickup_weapon; } var_7 = spawnstruct(); var_7.object = var_0; var_7.script_goal_radius = 12; var_7.should_abort = level.bot_funcs["dropped_weapon_cancel"]; var_7.action_thread = var_1; maps\mp\bots\_bots_strategy::bot_new_tactical_goal( "seek_dropped_weapon", var_0.origin, 100, var_7 ); } } bot_pickup_weapon( var_0 ) { self botpressbutton( "use", 2 ); wait 2; } should_stop_seeking_weapon( var_0 ) { if ( !isdefined( var_0.object ) ) return 1; if ( var_0.object.targetname == "dropped_weapon" ) { if ( maps\mp\bots\_bots_util::bot_get_total_gun_ammo() > 0 ) return 1; } else if ( var_0.object.targetname == "dropped_knife" ) { if ( maps\mp\bots\_bots_util::bot_in_combat() ) { self.going_for_knife = undefined; return 1; } } return 0; } bot_think_level_actions( var_0 ) { self notify( "bot_think_level_actions" ); self endon( "bot_think_level_actions" ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); for (;;) { common_scripts\utility::waittill_notify_or_timeout( "calculate_new_level_targets", randomfloatrange( 2, 10 ) ); if ( !isdefined( level.level_specific_bot_targets ) || level.level_specific_bot_targets.size == 0 ) continue; if ( maps\mp\bots\_bots_strategy::bot_has_tactical_goal( "map_interactive_object" ) ) continue; if ( maps\mp\bots\_bots_util::bot_in_combat() || maps\mp\bots\_bots_util::bot_is_remote_or_linked() ) continue; var_1 = undefined; foreach ( var_3 in level.level_specific_bot_targets ) { if ( common_scripts\utility::array_contains( var_3.high_priority_for, self ) ) { var_1 = var_3; break; } } if ( !isdefined( var_1 ) ) { if ( randomint( 100 ) > 25 ) continue; var_5 = common_scripts\utility::get_array_of_closest( self.origin, level.level_specific_bot_targets ); var_6 = 256; if ( isdefined( var_0 ) ) var_6 = var_0; else if ( self botgetscriptgoaltype() == "hunt" && self botpursuingscriptgoal() ) var_6 = 512; if ( distancesquared( self.origin, var_5[0].origin ) > var_6 * var_6 ) continue; var_1 = var_5[0]; } var_7 = 0; if ( var_1.bot_interaction_type == "damage" ) { var_7 = bot_should_melee_level_damage_target( var_1 ); if ( var_7 ) { var_8 = var_1.origin[2] - ( var_1.bot_targets[0].origin[2] + 55 ); var_9 = var_1.origin[2] - ( var_1.bot_targets[1].origin[2] + 55 ); if ( var_8 > 55 && var_9 > 55 ) { if ( common_scripts\utility::array_contains( var_1.high_priority_for, self ) ) var_1.high_priority_for = common_scripts\utility::array_remove( var_1.high_priority_for, self ); continue; } } var_10 = weaponclass( self getcurrentweapon() ); if ( var_10 == "spread" ) { var_11 = var_1.bot_targets[0].origin - var_1.origin; var_12 = var_1.bot_targets[1].origin - var_1.origin; var_13 = lengthsquared( var_11 ); var_14 = lengthsquared( var_12 ); if ( var_13 > 22500 && var_14 > 22500 ) { if ( common_scripts\utility::array_contains( var_1.high_priority_for, self ) ) var_1.high_priority_for = common_scripts\utility::array_remove( var_1.high_priority_for, self ); continue; } } } var_15 = spawnstruct(); var_15.object = var_1; if ( var_1.bot_interaction_type == "damage" ) { if ( var_7 ) var_15.should_abort = ::level_trigger_should_abort_melee; else var_15.should_abort = ::level_trigger_should_abort_ranged; } if ( var_1.bot_interaction_type == "use" ) { var_15.action_thread = ::use_use_trigger; var_15.should_abort = ::level_trigger_should_abort; var_15.script_goal_yaw = vectortoangles( var_1.origin - var_1.bot_target.origin )[1]; maps\mp\bots\_bots_strategy::bot_new_tactical_goal( "map_interactive_object", var_1.bot_target.origin, 10, var_15 ); continue; } if ( var_1.bot_interaction_type == "damage" ) { if ( var_7 ) { var_15.action_thread = ::melee_damage_trigger; var_15.script_goal_radius = 20; } else { var_15.action_thread = ::attack_damage_trigger; var_15.script_goal_radius = 50; } var_16 = undefined; var_17 = maps\mp\bots\_bots_util::bot_queued_process( "GetPathDistLevelAction", maps\mp\bots\_bots_util::func_get_path_dist, self.origin, var_1.bot_targets[0].origin ); var_18 = maps\mp\bots\_bots_util::bot_queued_process( "GetPathDistLevelAction", maps\mp\bots\_bots_util::func_get_path_dist, self.origin, var_1.bot_targets[1].origin ); if ( !isdefined( var_1 ) ) continue; if ( var_17 <= 0 && var_18 <= 0 ) continue; if ( var_17 > 0 ) { if ( var_18 < 0 || var_17 <= var_18 ) var_16 = var_1.bot_targets[0]; } if ( var_18 > 0 ) { if ( var_17 < 0 || var_18 <= var_17 ) var_16 = var_1.bot_targets[1]; } if ( !var_7 ) childthread monitor_node_visible( var_16 ); maps\mp\bots\_bots_strategy::bot_new_tactical_goal( "map_interactive_object", var_16.origin, 10, var_15 ); } } } bot_should_melee_level_damage_target( var_0 ) { var_1 = self getcurrentweapon(); var_2 = maps\mp\bots\_bots_util::bot_out_of_ammo() || self.hasriotshieldequipped || isdefined( self.isjuggernautmaniac ) && self.isjuggernautmaniac == 1 || weaponclass( var_1 ) == "grenade" || var_1 == "iw6_knifeonly_mp" || var_1 == "iw6_knifeonlyfast_mp"; return var_2; } monitor_node_visible( var_0 ) { self endon( "goal" ); wait 0.1; for (;;) { if ( weaponclass( self getcurrentweapon() ) == "spread" ) { if ( distancesquared( self.origin, var_0.origin ) > 90000 ) { wait 0.05; continue; } } var_1 = self getnearestnode(); if ( isdefined( var_1 ) ) { if ( nodesvisible( var_1, var_0 ) ) { if ( sighttracepassed( self.origin + ( 0, 0, 55 ), var_0.origin + ( 0, 0, 55 ), 0, self ) ) self notify( "goal" ); } } wait 0.05; } } attack_damage_trigger( var_0 ) { if ( var_0.object.origin[2] - self geteye()[2] > 55 ) { if ( distance2dsquared( var_0.object.origin, self.origin ) < 225 ) return; } self botsetflag( "disable_movement", 1 ); look_at_damage_trigger( var_0.object, 0.3 ); self botpressbutton( "ads", 0.3 ); wait 0.25; var_1 = gettime(); while ( isdefined( var_0.object ) && !isdefined( var_0.object.already_used ) && gettime() - var_1 < 5000 ) { look_at_damage_trigger( var_0.object, 0.15 ); self botpressbutton( "ads", 0.15 ); self botpressbutton( "attack" ); wait 0.1; } self botsetflag( "disable_movement", 0 ); } melee_damage_trigger( var_0 ) { self botsetflag( "disable_movement", 1 ); look_at_damage_trigger( var_0.object, 0.3 ); wait 0.25; var_1 = gettime(); while ( isdefined( var_0.object ) && !isdefined( var_0.object.already_used ) && gettime() - var_1 < 5000 ) { look_at_damage_trigger( var_0.object, 0.15 ); self botpressbutton( "melee" ); wait 0.1; } self botsetflag( "disable_movement", 0 ); } look_at_damage_trigger( var_0, var_1 ) { var_2 = var_0.origin; if ( distance2dsquared( self.origin, var_2 ) < 100 ) var_2 = ( var_2[0], var_2[1], self geteye()[2] ); self botlookatpoint( var_2, var_1, "script_forced" ); } use_use_trigger( var_0 ) { if ( isagent( self ) ) { common_scripts\utility::_enableusability(); var_0.object enableplayeruse( self ); wait 0.05; } var_1 = var_0.object.use_time; self botpressbutton( "use", var_1 ); wait( var_1 ); if ( isagent( self ) ) { common_scripts\utility::_disableusability(); if ( isdefined( var_0.object ) ) var_0.object disableplayeruse( self ); } } level_trigger_should_abort_melee( var_0 ) { if ( level_trigger_should_abort( var_0 ) ) return 1; if ( !bot_should_melee_level_damage_target( var_0.object ) ) return 1; return 0; } level_trigger_should_abort_ranged( var_0 ) { if ( level_trigger_should_abort( var_0 ) ) return 1; if ( bot_should_melee_level_damage_target( var_0.object ) ) return 1; return 0; } level_trigger_should_abort( var_0 ) { if ( !isdefined( var_0.object ) ) return 1; if ( isdefined( var_0.object.already_used ) ) return 1; if ( maps\mp\bots\_bots_util::bot_in_combat() ) return 1; return 0; } crate_in_range( var_0 ) { if ( !isdefined( var_0.owner ) || var_0.owner != self ) { if ( distancesquared( self.origin, var_0.origin ) > 4194304 ) return 0; } return 1; } bot_crate_valid( var_0 ) { if ( !isdefined( var_0 ) ) return 0; if ( !self [[ level.bot_funcs["crate_can_use"] ]]( var_0 ) ) return 0; if ( !crate_landed_and_on_path_grid( var_0 ) ) return 0; if ( level.teambased && isdefined( var_0.bomb ) && isdefined( var_0.team ) && var_0.team == self.team ) return 0; if ( !self [[ level.bot_funcs["crate_in_range"] ]]( var_0 ) ) return 0; if ( isdefined( var_0.boxtype ) ) { if ( isdefined( level.boxsettings[var_0.boxtype] ) && ![[ level.boxsettings[var_0.boxtype].canusecallback ]]() ) return 0; if ( isdefined( var_0.disabled_use_for ) && isdefined( var_0.disabled_use_for[self getentitynumber()] ) && var_0.disabled_use_for[self getentitynumber()] ) return 0; if ( !self [[ level.bot_can_use_box_by_type[var_0.boxtype] ]]( var_0 ) ) return 0; } return isdefined( var_0 ); } crate_landed_and_on_path_grid( var_0 ) { if ( !crate_has_landed( var_0 ) ) return 0; if ( !crate_is_on_path_grid( var_0 ) ) return 0; return isdefined( var_0 ); } crate_has_landed( var_0 ) { if ( isdefined( var_0.boxtype ) ) return gettime() > var_0.birthtime + 1000; else return isdefined( var_0.droppingtoground ) && !var_0.droppingtoground; } crate_is_on_path_grid( var_0 ) { if ( !isdefined( var_0.on_path_grid ) ) crate_calculate_on_path_grid( var_0 ); return isdefined( var_0 ) && var_0.on_path_grid; } node_within_use_radius_of_crate( var_0, var_1 ) { if ( isdefined( var_1.boxtype ) && var_1.boxtype == "scavenger_bag" ) return abs( var_0.origin[0] - var_1.origin[0] ) < 36 && abs( var_0.origin[0] - var_1.origin[0] ) < 36 && abs( var_0.origin[0] - var_1.origin[0] ) < 18; else { var_2 = getdvarfloat( "player_useRadius" ); var_3 = distancesquared( var_1.origin, var_0.origin + ( 0, 0, 40 ) ); return var_3 <= var_2 * var_2; } } crate_calculate_on_path_grid( var_0 ) { var_0 thread crate_monitor_position(); var_0.on_path_grid = 0; var_1 = undefined; var_2 = undefined; if ( isdefined( var_0.forcedisconnectuntil ) ) { var_1 = var_0.forcedisconnectuntil; var_2 = gettime() + 30000; var_0.forcedisconnectuntil = var_2; var_0 notify( "path_disconnect" ); } wait 0.05; if ( !isdefined( var_0 ) ) return; var_3 = crate_get_nearest_valid_nodes( var_0 ); if ( !isdefined( var_0 ) ) return; if ( isdefined( var_3 ) && var_3.size > 0 ) { var_0.nearest_nodes = var_3; var_0.on_path_grid = 1; } else { var_4 = getdvarfloat( "player_useRadius" ); var_5 = getnodesinradiussorted( var_0.origin, var_4 * 2, 0 )[0]; var_6 = var_0 getpointinbounds( 0, 0, -1 ); var_7 = undefined; if ( isdefined( var_0.boxtype ) && var_0.boxtype == "scavenger_bag" ) { if ( maps\mp\bots\_bots_util::bot_point_is_on_pathgrid( var_0.origin ) ) var_7 = var_0.origin; } else var_7 = botgetclosestnavigablepoint( var_0.origin, var_4 ); if ( isdefined( var_5 ) && !var_5 nodeisdisconnected() && isdefined( var_7 ) && abs( var_5.origin[2] - var_6[2] ) < 30 ) { var_0.nearest_points = [ var_7 ]; var_0.nearest_nodes = [ var_5 ]; var_0.on_path_grid = 1; } } if ( isdefined( var_0.forcedisconnectuntil ) ) { if ( var_0.forcedisconnectuntil == var_2 ) var_0.forcedisconnectuntil = var_1; } } crate_get_nearest_valid_nodes( var_0 ) { var_1 = getnodesinradiussorted( var_0.origin, 256, 0 ); for ( var_2 = var_1.size; var_2 > 0; var_2-- ) var_1[var_2] = var_1[var_2 - 1]; var_1[0] = getclosestnodeinsight( var_0.origin ); var_3 = undefined; if ( isdefined( var_0.forcedisconnectuntil ) ) var_3 = getallnodes(); var_4 = []; var_5 = 1; if ( !isdefined( var_0.boxtype ) ) var_5 = 2; for ( var_2 = 0; var_2 < var_1.size; var_2++ ) { var_6 = var_1[var_2]; if ( !isdefined( var_6 ) || !isdefined( var_0 ) ) continue; if ( var_6 nodeisdisconnected() ) continue; if ( !node_within_use_radius_of_crate( var_6, var_0 ) ) { if ( var_2 == 0 ) continue; else break; } wait 0.05; if ( !isdefined( var_0 ) ) break; if ( sighttracepassed( var_0.origin, var_6.origin + ( 0, 0, 55 ), 0, var_0 ) ) { wait 0.05; if ( !isdefined( var_0 ) ) break; if ( !isdefined( var_0.forcedisconnectuntil ) ) { var_4[var_4.size] = var_6; if ( var_4.size == var_5 ) return var_4; else continue; } var_7 = undefined; var_8 = 0; while ( !isdefined( var_7 ) && var_8 < 100 ) { var_8++; var_9 = common_scripts\utility::random( var_3 ); if ( distancesquared( var_6.origin, var_9.origin ) > 250000 ) var_7 = var_9; } if ( isdefined( var_7 ) ) { var_10 = maps\mp\bots\_bots_util::bot_queued_process( "GetNodesOnPathCrate", maps\mp\bots\_bots_util::func_get_nodes_on_path, var_6.origin, var_7.origin ); if ( isdefined( var_10 ) ) { var_4[var_4.size] = var_6; if ( var_4.size == var_5 ) return var_4; else continue; } } } } return undefined; } crate_get_bot_target( var_0 ) { if ( isdefined( var_0.nearest_points ) ) return var_0.nearest_points[0]; if ( isdefined( var_0.nearest_nodes ) ) { if ( var_0.nearest_nodes.size > 1 ) { var_1 = common_scripts\utility::array_reverse( self botnodescoremultiple( var_0.nearest_nodes, "node_exposed" ) ); return common_scripts\utility::random_weight_sorted( var_1 ).origin; } else return var_0.nearest_nodes[0].origin; } } crate_get_bot_target_check_distance( var_0, var_1 ) { var_2 = crate_get_bot_target( var_0 ); var_3 = var_1 * 0.9; var_3 = var_3 * var_3; if ( distancesquared( var_0.origin, var_2 ) <= var_3 ) return var_2; else return undefined; } bot_think_crate() { self notify( "bot_think_crate" ); self endon( "bot_think_crate" ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); var_0 = getdvarfloat( "player_useRadius" ); for (;;) { var_1 = randomfloatrange( 2, 4 ); common_scripts\utility::waittill_notify_or_timeout( "new_crate_to_take", var_1 ); if ( isdefined( self.boxes ) && self.boxes.size == 0 ) self.boxes = undefined; var_2 = level.carepackages; if ( !maps\mp\bots\_bots_util::bot_in_combat() && isdefined( self.boxes ) ) var_2 = common_scripts\utility::array_combine( var_2, self.boxes ); if ( isdefined( level.bot_scavenger_bags ) && maps\mp\_utility::_hasperk( "specialty_scavenger" ) ) var_2 = common_scripts\utility::array_combine( var_2, level.bot_scavenger_bags ); var_2 = common_scripts\utility::array_removeundefined( var_2 ); if ( var_2.size == 0 ) continue; if ( maps\mp\bots\_bots_strategy::bot_has_tactical_goal( "airdrop_crate" ) || self botgetscriptgoaltype() == "tactical" || maps\mp\bots\_bots_util::bot_is_remote_or_linked() ) continue; var_3 = []; foreach ( var_5 in var_2 ) { if ( bot_crate_valid( var_5 ) ) var_3[var_3.size] = var_5; } var_3 = common_scripts\utility::array_remove_duplicates( var_3 ); if ( var_3.size == 0 ) continue; var_3 = common_scripts\utility::get_array_of_closest( self.origin, var_3 ); var_7 = self getnearestnode(); if ( !isdefined( var_7 ) ) continue; var_8 = self [[ level.bot_funcs["crate_low_ammo_check"] ]](); var_9 = ( var_8 || randomint( 100 ) < 50 ) && !maps\mp\_utility::isemped(); var_10 = undefined; foreach ( var_5 in var_3 ) { var_12 = 0; if ( ( !isdefined( var_5.owner ) || var_5.owner != self ) && !isdefined( var_5.boxtype ) ) { var_13 = []; foreach ( var_15 in level.players ) { if ( !isdefined( var_15.team ) ) continue; if ( !isai( var_15 ) && level.teambased && var_15.team == self.team ) { if ( distancesquared( var_15.origin, var_5.origin ) < 490000 ) var_13[var_13.size] = var_15; } } if ( var_13.size > 0 ) { var_17 = var_13[0] getnearestnode(); if ( isdefined( var_17 ) ) { var_12 = 0; foreach ( var_19 in var_5.nearest_nodes ) var_12 = var_12 | nodesvisible( var_17, var_19, 1 ); } } } if ( !var_12 ) { var_21 = isdefined( var_5.bots ) && isdefined( var_5.bots[self.team] ) && var_5.bots[self.team] > 0; var_22 = 0; foreach ( var_19 in var_5.nearest_nodes ) var_22 = var_22 | nodesvisible( var_7, var_19, 1 ); if ( var_22 || var_9 && !var_21 ) { var_10 = var_5; break; } } } if ( isdefined( var_10 ) ) { if ( self [[ level.bot_funcs["crate_should_claim"] ]]() ) { if ( !isdefined( var_10.boxtype ) ) { if ( !isdefined( var_10.bots ) ) var_10.bots = []; var_10.bots[self.team] = 1; } } var_26 = spawnstruct(); var_26.object = var_10; var_26.start_thread = ::watch_bot_died_during_crate; var_26.should_abort = ::crate_picked_up; var_27 = undefined; if ( isdefined( var_10.boxtype ) ) { if ( isdefined( var_10.boxtouchonly ) && var_10.boxtouchonly ) { var_26.script_goal_radius = 16; var_26.action_thread = undefined; var_27 = var_10.origin; } else { var_26.script_goal_radius = 50; var_26.action_thread = ::use_box; var_28 = crate_get_bot_target_check_distance( var_10, var_0 ); if ( !isdefined( var_28 ) ) continue; var_28 = var_28 - var_10.origin; var_29 = length( var_28 ) * randomfloat( 1.0 ); var_27 = var_10.origin + vectornormalize( var_28 ) * var_29 + ( 0, 0, 12 ); } } else { var_26.action_thread = ::use_crate; var_26.end_thread = ::stop_using_crate; var_27 = crate_get_bot_target_check_distance( var_10, var_0 ); if ( !isdefined( var_27 ) ) continue; var_26.script_goal_radius = var_0 - distance( var_10.origin, var_27 + ( 0, 0, 40 ) ); var_27 = var_27 + ( 0, 0, 24 ); } if ( isdefined( var_26.script_goal_radius ) ) { } var_10 notify( "path_disconnect" ); wait 0.05; if ( !isdefined( var_10 ) ) continue; maps\mp\bots\_bots_strategy::bot_new_tactical_goal( "airdrop_crate", var_27, 30, var_26 ); } } } bot_should_use_ballistic_vest_crate( var_0 ) { return 1; } crate_should_claim() { return 1; } crate_low_ammo_check() { return 0; } bot_should_use_ammo_crate( var_0 ) { if ( self getcurrentweapon() == level.boxsettings[var_0.boxtype].minigunweapon ) return 0; return 1; } bot_pre_use_ammo_crate( var_0 ) { self switchtoweapon( self.secondaryweapon ); wait 1.0; } bot_post_use_ammo_crate( var_0 ) { self switchtoweapon( "none" ); self.secondaryweapon = self getcurrentweapon(); } bot_should_use_scavenger_bag( var_0 ) { if ( maps\mp\bots\_bots_util::bot_get_low_on_ammo( 0.66 ) ) { var_1 = self getnearestnode(); if ( isdefined( var_0.nearest_nodes ) && isdefined( var_0.nearest_nodes[0] ) && isdefined( var_1 ) ) { if ( nodesvisible( var_1, var_0.nearest_nodes[0], 1 ) ) { if ( common_scripts\utility::within_fov( self.origin, self.angles, var_0.origin, self botgetfovdot() ) ) return 1; } } } return 0; } bot_should_use_grenade_crate( var_0 ) { var_1 = self getweaponslistoffhands(); foreach ( var_3 in var_1 ) { if ( self getweaponammostock( var_3 ) == 0 ) return 1; } return 0; } bot_should_use_juicebox_crate( var_0 ) { return 1; } crate_monitor_position() { self notify( "crate_monitor_position" ); self endon( "crate_monitor_position" ); self endon( "death" ); level endon( "game_ended" ); for (;;) { var_0 = self.origin; wait 0.5; if ( !isalive( self ) ) return; if ( !maps\mp\bots\_bots_util::bot_vectors_are_equal( self.origin, var_0 ) ) { self.on_path_grid = undefined; self.nearest_nodes = undefined; self.nearest_points = undefined; } } } crate_wait_use() { } crate_picked_up( var_0 ) { if ( !isdefined( var_0.object ) ) return 1; return 0; } use_crate( var_0 ) { if ( isagent( self ) ) { common_scripts\utility::_enableusability(); var_0.object enableplayeruse( self ); wait 0.05; } self [[ level.bot_funcs["crate_wait_use"] ]](); if ( isdefined( var_0.object.owner ) && var_0.object.owner == self ) var_1 = level.crateownerusetime / 1000 + 0.5; else var_1 = level.cratenonownerusetime / 1000 + 1.0; self botpressbutton( "use", var_1 ); wait( var_1 ); if ( isagent( self ) ) { common_scripts\utility::_disableusability(); if ( isdefined( var_0.object ) ) var_0.object disableplayeruse( self ); } if ( isdefined( var_0.object ) ) { if ( !isdefined( var_0.object.bots_used ) ) var_0.object.bots_used = []; var_0.object.bots_used[var_0.object.bots_used.size] = self; } } use_box( var_0 ) { if ( isagent( self ) ) { common_scripts\utility::_enableusability(); var_0.object enableplayeruse( self ); wait 0.05; } if ( isdefined( var_0.object ) && isdefined( var_0.object.boxtype ) ) { var_1 = var_0.object.boxtype; if ( isdefined( level.bot_pre_use_box_of_type[var_1] ) ) self [[ level.bot_pre_use_box_of_type[var_1] ]]( var_0.object ); if ( isdefined( var_0.object ) ) { var_2 = level.boxsettings[var_0.object.boxtype].usetime / 1000 + 0.5; self botpressbutton( "use", var_2 ); wait( var_2 ); if ( isdefined( level.bot_post_use_box_of_type[var_1] ) ) self [[ level.bot_post_use_box_of_type[var_1] ]]( var_0.object ); } } if ( isagent( self ) ) { common_scripts\utility::_disableusability(); if ( isdefined( var_0.object ) ) var_0.object disableplayeruse( self ); } } watch_bot_died_during_crate( var_0 ) { thread bot_watch_for_death( var_0.object ); } stop_using_crate( var_0 ) { if ( isdefined( var_0.object ) ) var_0.object.bots[self.team] = 0; } bot_watch_for_death( var_0 ) { var_0 endon( "death" ); var_0 endon( "revived" ); var_0 endon( "disconnect" ); level endon( "game_ended" ); var_1 = self.team; common_scripts\utility::waittill_any( "death", "disconnect" ); if ( isdefined( var_0 ) ) var_0.bots[var_1] = 0; } bot_think_crate_blocking_path() { self notify( "bot_think_crate_blocking_path" ); self endon( "bot_think_crate_blocking_path" ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); var_0 = getdvarfloat( "player_useRadius" ); for (;;) { wait 3; if ( self usebuttonpressed() ) continue; if ( maps\mp\_utility::isusingremote() ) continue; var_1 = level.carepackages; for ( var_2 = 0; var_2 < var_1.size; var_2++ ) { var_3 = var_1[var_2]; if ( !isdefined( var_3 ) ) continue; if ( distancesquared( self.origin, var_3.origin ) < var_0 * var_0 ) { if ( var_3.owner == self ) { self botpressbutton( "use", level.crateownerusetime / 1000 + 0.5 ); continue; } self botpressbutton( "use", level.cratenonownerusetime / 1000 + 0.5 ); } } } } bot_think_revive() { self notify( "bot_think_revive" ); self endon( "bot_think_revive" ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); if ( !level.teambased ) return; for (;;) { var_0 = 2.0; var_1 = getentarray( "revive_trigger", "targetname" ); if ( var_1.size > 0 ) var_0 = 0.05; level common_scripts\utility::waittill_notify_or_timeout( "player_last_stand", var_0 ); if ( !bot_can_revive() ) continue; var_1 = getentarray( "revive_trigger", "targetname" ); if ( var_1.size > 1 ) { var_1 = sortbydistance( var_1, self.origin ); if ( isdefined( self.owner ) ) { for ( var_2 = 0; var_2 < var_1.size; var_2++ ) { if ( var_1[var_2].owner != self.owner ) continue; if ( var_2 == 0 ) break; var_3 = var_1[var_2]; var_1[var_2] = var_1[0]; var_1[0] = var_3; break; } } } for ( var_2 = 0; var_2 < var_1.size; var_2++ ) { var_4 = var_1[var_2]; var_5 = var_4.owner; if ( !isdefined( var_5 ) ) continue; if ( var_5 == self ) continue; if ( !isalive( var_5 ) ) continue; if ( var_5.team != self.team ) continue; if ( !isdefined( var_5.inlaststand ) || !var_5.inlaststand ) continue; if ( isdefined( var_5.bots ) && isdefined( var_5.bots[self.team] ) && var_5.bots[self.team] > 0 ) continue; if ( distancesquared( self.origin, var_5.origin ) < 4194304 ) { var_6 = spawnstruct(); var_6.object = var_4; var_6.script_goal_radius = 64; if ( isdefined( self.last_revive_fail_time ) && gettime() - self.last_revive_fail_time < 1000 ) var_6.script_goal_radius = 32; var_6.start_thread = ::watch_bot_died_during_revive; var_6.end_thread = ::stop_reviving; var_6.should_abort = ::player_revived_or_dead; var_6.action_thread = ::revive_player; maps\mp\bots\_bots_strategy::bot_new_tactical_goal( "revive", var_5.origin, 60, var_6 ); break; } } } } watch_bot_died_during_revive( var_0 ) { thread bot_watch_for_death( var_0.object.owner ); } stop_reviving( var_0 ) { if ( isdefined( var_0.object.owner ) ) var_0.object.owner.bots[self.team] = 0; } player_revived_or_dead( var_0 ) { if ( !isdefined( var_0.object.owner ) || var_0.object.owner.health <= 0 ) return 1; if ( !isdefined( var_0.object.owner.inlaststand ) || !var_0.object.owner.inlaststand ) return 1; return 0; } revive_player( var_0 ) { if ( distancesquared( self.origin, var_0.object.owner.origin ) > 4096 ) { self.last_revive_fail_time = gettime(); return; } if ( isagent( self ) ) { common_scripts\utility::_enableusability(); var_0.object enableplayeruse( self ); wait 0.05; } var_1 = self.team; self botpressbutton( "use", level.laststandusetime / 1000 + 0.5 ); wait( level.laststandusetime / 1000 + 1.5 ); if ( isdefined( var_0.object.owner ) ) var_0.object.bots[var_1] = 0; if ( isagent( self ) ) { common_scripts\utility::_disableusability(); if ( isdefined( var_0.object ) ) var_0.object disableplayeruse( self ); } } bot_can_revive() { if ( isdefined( self.laststand ) && self.laststand == 1 ) return 0; if ( maps\mp\bots\_bots_strategy::bot_has_tactical_goal( "revive" ) ) return 0; if ( maps\mp\bots\_bots_util::bot_is_remote_or_linked() ) return 0; if ( maps\mp\bots\_bots_util::bot_is_bodyguarding() ) return 1; var_0 = self botgetscriptgoaltype(); if ( var_0 == "none" || var_0 == "hunt" || var_0 == "guard" ) return 1; return 0; } revive_watch_for_finished( var_0 ) { self endon( "death" ); self endon( "disconnect" ); self endon( "bad_path" ); self endon( "goal" ); var_0 common_scripts\utility::waittill_any( "death", "revived" ); self notify( "bad_path" ); } bot_know_enemies_on_start() { self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); if ( gettime() > 15000 ) return; while ( !maps\mp\_utility::gamehasstarted() || !maps\mp\_utility::gameflag( "prematch_done" ) ) wait 0.05; var_0 = undefined; var_1 = undefined; for ( var_2 = 0; var_2 < level.players.size; var_2++ ) { var_3 = level.players[var_2]; if ( isdefined( var_3 ) && isdefined( self.team ) && isdefined( var_3.team ) && isenemyteam( self.team, var_3.team ) ) { if ( !isdefined( var_3.bot_start_known_by_enemy ) ) var_0 = var_3; if ( isai( var_3 ) && !isdefined( var_3.bot_start_know_enemy ) ) var_1 = var_3; } } if ( isdefined( var_0 ) ) { self.bot_start_know_enemy = 1; var_0.bot_start_known_by_enemy = 1; self getenemyinfo( var_0 ); } if ( isdefined( var_1 ) ) { var_1.bot_start_know_enemy = 1; self.bot_start_known_by_enemy = 1; var_1 getenemyinfo( self ); } } bot_make_entity_sentient( var_0, var_1 ) { if ( isdefined( var_1 ) ) return self makeentitysentient( var_0, var_1 ); else return self makeentitysentient( var_0 ); } bot_think_gametype() { self notify( "bot_think_gametype" ); self endon( "bot_think_gametype" ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); maps\mp\_utility::gameflagwait( "prematch_done" ); self thread [[ level.bot_funcs["gametype_think"] ]](); } default_gametype_think() { } monitor_smoke_grenades() { for (;;) { level waittill( "smoke", var_0, var_1 ); if ( var_1 == "smoke_grenade_mp" || var_1 == "smoke_grenadejugg_mp" || var_1 == "odin_projectile_smoke_mp" ) { var_0 thread handle_smoke( 9.0 ); continue; } if ( var_1 == "odin_projectile_large_rod_mp" ) var_0 thread handle_smoke( 2.5 ); } } handle_smoke( var_0 ) { self waittill( "explode", var_1 ); var_2 = common_scripts\utility::spawn_tag_origin(); var_2 show(); var_2.origin = var_1; var_3 = 0.8; wait( var_3 ); var_3 = 0.5; var_4 = getent( "smoke_grenade_sight_clip_64_short", "targetname" ); if ( isdefined( var_4 ) ) var_2 clonebrushmodeltoscriptmodel( var_4 ); wait( var_3 ); var_3 = 0.6; var_5 = getent( "smoke_grenade_sight_clip_64_tall", "targetname" ); if ( isdefined( var_5 ) ) var_2 clonebrushmodeltoscriptmodel( var_5 ); wait( var_3 ); var_3 = var_0; var_6 = getent( "smoke_grenade_sight_clip_256", "targetname" ); if ( isdefined( var_6 ) ) var_2 clonebrushmodeltoscriptmodel( var_6 ); wait( var_3 ); var_2 delete(); } bot_add_scavenger_bag( var_0 ) { var_1 = 0; var_0.boxtype = "scavenger_bag"; var_0.boxtouchonly = 1; if ( !isdefined( level.bot_scavenger_bags ) ) level.bot_scavenger_bags = []; foreach ( var_4, var_3 in level.bot_scavenger_bags ) { if ( !isdefined( var_3 ) ) { var_1 = 1; level.bot_scavenger_bags[var_4] = var_0; break; } } if ( !var_1 ) level.bot_scavenger_bags[level.bot_scavenger_bags.size] = var_0; foreach ( var_6 in level.participants ) { if ( isai( var_6 ) && var_6 maps\mp\_utility::_hasperk( "specialty_scavenger" ) ) var_6 notify( "new_crate_to_take" ); } } bot_triggers() { var_0 = getentarray( "bot_flag_set", "targetname" ); foreach ( var_2 in var_0 ) { if ( !isdefined( var_2.script_noteworthy ) ) continue; var_2 thread bot_flag_trigger( var_2.script_noteworthy ); } } bot_flag_trigger( var_0 ) { self endon( "death" ); for (;;) { self waittill( "trigger", var_1 ); if ( maps\mp\_utility::isaigameparticipant( var_1 ) ) { var_1 notify( "flag_trigger_set_" + var_0 ); var_1 botsetflag( var_0, 1 ); var_1 thread bot_flag_trigger_clear( var_0 ); } } } bot_flag_trigger_clear( var_0 ) { self endon( "flag_trigger_set_" + var_0 ); self endon( "death" ); self endon( "disconnect" ); level endon( "game_ended" ); common_scripts\utility::waitframe(); waittillframeend; self botsetflag( var_0, 0 ); }