iw6-scripts/maps/mp/bots/_bots_strategy.gsc
2024-02-13 13:20:49 +01:00

1720 lines
51 KiB
Plaintext

// IW6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
bot_defend_get_random_entrance_point_for_current_area()
{
var_0 = bot_defend_get_precalc_entrances_for_current_area( self.cur_defend_stance );
if ( isdefined( var_0 ) && var_0.size > 0 )
return common_scripts\utility::random( var_0 ).origin;
return undefined;
}
bot_defend_get_precalc_entrances_for_current_area( var_0 )
{
if ( isdefined( self.defend_entrance_index ) )
return maps\mp\bots\_bots_util::bot_get_entrances_for_stance_and_index( var_0, self.defend_entrance_index );
return [];
}
bot_setup_bombzone_bottargets()
{
wait 1.0;
bot_setup_bot_targets( level.bombzones );
level.bot_set_bombzone_bottargets = 1;
}
bot_setup_radio_bottargets()
{
bot_setup_bot_targets( level.radios );
}
bot_setup_bot_targets( var_0 )
{
foreach ( var_2 in var_0 )
{
if ( !isdefined( var_2.bottargets ) )
{
var_2.bottargets = [];
var_3 = gettnodesintrigger( var_2.trigger );
foreach ( var_5 in var_3 )
{
if ( !var_5 nodeisdisconnected() )
var_2.bottargets = common_scripts\utility::array_add( var_2.bottargets, var_5 );
}
}
}
}
bot_get_ambush_trap_item( var_0, var_1, var_2 )
{
var_3 = [];
var_4 = [];
var_4[var_4.size] = var_0;
if ( isdefined( var_1 ) )
var_4[var_4.size] = var_1;
if ( isdefined( var_1 ) )
var_4[var_4.size] = var_2;
foreach ( var_6 in var_4 )
{
var_3["purpose"] = var_6;
var_3["item_action"] = maps\mp\bots\_bots_util::bot_get_grenade_for_purpose( var_6 );
if ( isdefined( var_3["item_action"] ) )
return var_3;
}
}
bot_set_ambush_trap( var_0, var_1, var_2, var_3, var_4 )
{
self notify( "bot_set_ambush_trap" );
self endon( "bot_set_ambush_trap" );
if ( !isdefined( var_0 ) )
return 0;
var_5 = undefined;
if ( !isdefined( var_4 ) && isdefined( var_1 ) && var_1.size > 0 )
{
if ( !isdefined( var_2 ) )
return 0;
var_6 = [];
var_7 = undefined;
if ( isdefined( var_3 ) )
var_7 = anglestoforward( ( 0, var_3, 0 ) );
foreach ( var_9 in var_1 )
{
if ( !isdefined( var_7 ) )
{
var_6[var_6.size] = var_9;
continue;
}
if ( distancesquared( var_9.origin, var_2.origin ) > 90000 )
{
if ( vectordot( var_7, vectornormalize( var_9.origin - var_2.origin ) ) < 0.4 )
var_6[var_6.size] = var_9;
}
}
if ( var_6.size > 0 )
{
var_5 = common_scripts\utility::random( var_6 );
var_11 = getnodesinradius( var_5.origin, 300, 50 );
var_12 = [];
foreach ( var_14 in var_11 )
{
if ( !isdefined( var_14.bot_ambush_end ) )
var_12[var_12.size] = var_14;
}
var_11 = var_12;
var_4 = self botnodepick( var_11, min( var_11.size, 3 ), "node_trap", var_2, var_5 );
}
}
if ( isdefined( var_4 ) )
{
var_16 = undefined;
if ( var_0["purpose"] == "trap_directional" && isdefined( var_5 ) )
{
var_17 = vectortoangles( var_5.origin - var_4.origin );
var_16 = var_17[1];
}
if ( self bothasscriptgoal() && self botgetscriptgoaltype() != "critical" && self botgetscriptgoaltype() != "tactical" )
self botclearscriptgoal();
var_18 = self botsetscriptgoalnode( var_4, "guard", var_16 );
if ( var_18 )
{
var_19 = maps\mp\bots\_bots_util::bot_waittill_goal_or_fail();
if ( var_19 == "goal" )
{
thread maps\mp\bots\_bots_util::bot_force_stance_for_time( "stand", 5.0 );
if ( !isdefined( self.enemy ) || 0 == self botcanseeentity( self.enemy ) )
{
if ( isdefined( var_16 ) )
self botthrowgrenade( var_5.origin, var_0["item_action"] );
else
self botthrowgrenade( self.origin + anglestoforward( self.angles ) * 50, var_0["item_action"] );
self.ambush_trap_ent = undefined;
thread bot_set_ambush_trap_wait_fire( "grenade_fire" );
thread bot_set_ambush_trap_wait_fire( "missile_fire" );
var_20 = 3.0;
if ( var_0["purpose"] == "tacticalinsertion" )
var_20 = 6.0;
common_scripts\utility::waittill_any_timeout( var_20, "missile_fire", "grenade_fire" );
wait 0.05;
self notify( "ambush_trap_ent" );
if ( isdefined( self.ambush_trap_ent ) && var_0["purpose"] == "c4" )
thread bot_watch_manual_detonate( self.ambush_trap_ent, var_0["item_action"], 300 );
self.ambush_trap_ent = undefined;
wait( randomfloat( 0.25 ) );
self botsetstance( "none" );
}
}
return 1;
}
}
return 0;
}
bot_set_ambush_trap_wait_fire( var_0 )
{
self endon( "death" );
self endon( "disconnect" );
self endon( "bot_set_ambush_trap" );
self endon( "ambush_trap_ent" );
level endon( "game_ended" );
self waittill( var_0, var_1 );
self.ambush_trap_ent = var_1;
}
bot_watch_manual_detonate( var_0, var_1, var_2 )
{
self endon( "death" );
self endon( "disconnect" );
var_0 endon( "death" );
level endon( "game_ended" );
var_3 = var_2 * var_2;
for (;;)
{
if ( isdefined( var_0.origin ) && distancesquared( self.origin, var_0.origin ) > var_3 )
{
var_4 = self getclosestenemysqdist( var_0.origin, 1.0 );
if ( var_4 < var_3 )
{
self botpressbutton( var_1 );
return;
}
}
wait( randomfloatrange( 0.25, 1.0 ) );
}
}
bot_capture_point( var_0, var_1, var_2 )
{
thread bot_defend_think( var_0, var_1, "capture", var_2 );
}
bot_capture_zone( var_0, var_1, var_2, var_3 )
{
var_3["capture_trigger"] = var_2;
thread bot_defend_think( var_0, var_1, "capture_zone", var_3 );
}
bot_protect_point( var_0, var_1, var_2 )
{
if ( !isdefined( var_2 ) || !isdefined( var_2["min_goal_time"] ) )
var_2["min_goal_time"] = 12;
if ( !isdefined( var_2 ) || !isdefined( var_2["max_goal_time"] ) )
var_2["max_goal_time"] = 18;
thread bot_defend_think( var_0, var_1, "protect", var_2 );
}
bot_patrol_area( var_0, var_1, var_2 )
{
if ( !isdefined( var_2 ) || !isdefined( var_2["min_goal_time"] ) )
var_2["min_goal_time"] = 0.0;
if ( !isdefined( var_2 ) || !isdefined( var_2["max_goal_time"] ) )
var_2["max_goal_time"] = 0.01;
thread bot_defend_think( var_0, var_1, "patrol", var_2 );
}
bot_guard_player( var_0, var_1, var_2 )
{
if ( !isdefined( var_2 ) || !isdefined( var_2["min_goal_time"] ) )
var_2["min_goal_time"] = 15;
if ( !isdefined( var_2 ) || !isdefined( var_2["max_goal_time"] ) )
var_2["max_goal_time"] = 20;
thread bot_defend_think( var_0, var_1, "bodyguard", var_2 );
}
bot_defend_think( var_0, var_1, var_2, var_3 )
{
self notify( "started_bot_defend_think" );
self endon( "started_bot_defend_think" );
self endon( "death" );
self endon( "disconnect" );
level endon( "game_ended" );
self endon( "defend_stop" );
thread defense_death_monitor();
if ( isdefined( self.bot_defending ) || self botgetscriptgoaltype() == "camp" )
self botclearscriptgoal();
self.bot_defending = 1;
self.bot_defending_type = var_2;
if ( var_2 == "capture_zone" )
{
self.bot_defending_radius = undefined;
self.bot_defending_nodes = var_1;
self.bot_defending_trigger = var_3["capture_trigger"];
}
else
{
self.bot_defending_radius = var_1;
self.bot_defending_nodes = undefined;
self.bot_defending_trigger = undefined;
}
if ( maps\mp\_utility::isgameparticipant( var_0 ) )
{
self.bot_defend_player_guarding = var_0;
childthread monitor_defend_player();
}
else
{
self.bot_defend_player_guarding = undefined;
self.bot_defending_center = var_0;
}
self botsetstance( "none" );
var_4 = undefined;
var_5 = 6;
var_6 = 10;
if ( isdefined( var_3 ) )
{
self.defend_entrance_index = var_3["entrance_points_index"];
self.defense_score_flags = var_3["score_flags"];
self.bot_defending_override_origin_node = var_3["override_origin_node"];
if ( isdefined( var_3["override_goal_type"] ) )
var_4 = var_3["override_goal_type"];
if ( isdefined( var_3["min_goal_time"] ) )
var_5 = var_3["min_goal_time"];
if ( isdefined( var_3["max_goal_time"] ) )
var_6 = var_3["max_goal_time"];
if ( isdefined( var_3["override_entrances"] ) && var_3["override_entrances"].size > 0 )
{
self.defense_override_entrances = var_3["override_entrances"];
self.defend_entrance_index = self.name + " " + gettime();
foreach ( var_8 in self.defense_override_entrances )
{
var_8.prone_visible_from[self.defend_entrance_index] = maps\mp\bots\_bots_util::entrance_visible_from( var_8.origin, maps\mp\bots\_bots_util::defend_valid_center(), "prone" );
wait 0.05;
var_8.crouch_visible_from[self.defend_entrance_index] = maps\mp\bots\_bots_util::entrance_visible_from( var_8.origin, maps\mp\bots\_bots_util::defend_valid_center(), "crouch" );
wait 0.05;
}
}
}
if ( !isdefined( self.bot_defend_player_guarding ) )
{
var_10 = undefined;
if ( isdefined( var_3 ) && isdefined( var_3["nearest_node_to_center"] ) )
var_10 = var_3["nearest_node_to_center"];
if ( !isdefined( var_10 ) && isdefined( self.bot_defending_override_origin_node ) )
var_10 = self.bot_defending_override_origin_node;
if ( !isdefined( var_10 ) && isdefined( self.bot_defending_trigger ) && isdefined( self.bot_defending_trigger.nearest_node ) )
var_10 = self.bot_defending_trigger.nearest_node;
if ( !isdefined( var_10 ) )
var_10 = getclosestnodeinsight( maps\mp\bots\_bots_util::defend_valid_center() );
if ( !isdefined( var_10 ) )
{
var_11 = maps\mp\bots\_bots_util::defend_valid_center();
var_12 = getnodesinradiussorted( var_11, 256, 0 );
for ( var_13 = 0; var_13 < var_12.size; var_13++ )
{
var_14 = vectornormalize( var_12[var_13].origin - var_11 );
var_15 = var_11 + var_14 * 15;
if ( sighttracepassed( var_15, var_12[var_13].origin, 0, undefined ) )
{
var_10 = var_12[var_13];
break;
}
wait 0.05;
if ( sighttracepassed( var_15 + ( 0, 0, 55 ), var_12[var_13].origin + ( 0, 0, 55 ), 0, undefined ) )
{
var_10 = var_12[var_13];
break;
}
wait 0.05;
}
}
self.node_closest_to_defend_center = var_10;
}
var_16 = level.bot_find_defend_node_func[var_2];
if ( !isdefined( var_4 ) )
{
var_4 = "guard";
if ( var_2 == "capture" || var_2 == "capture_zone" )
var_4 = "objective";
}
var_17 = maps\mp\bots\_bots_util::bot_is_capturing();
if ( var_2 == "protect" )
childthread protect_watch_allies();
for (;;)
{
self.prev_defend_node = self.cur_defend_node;
self.cur_defend_node = undefined;
self.cur_defend_angle_override = undefined;
self.cur_defend_point_override = undefined;
self.cur_defend_stance = calculate_defend_stance( var_17 );
var_18 = self botgetscriptgoaltype();
var_19 = maps\mp\bots\_bots_util::bot_goal_can_override( var_4, var_18 );
if ( !var_19 )
{
wait 0.25;
continue;
}
var_20 = var_5;
var_21 = var_6;
var_22 = 1;
if ( isdefined( self.defense_investigate_specific_point ) )
{
self.cur_defend_point_override = self.defense_investigate_specific_point;
self.defense_investigate_specific_point = undefined;
var_22 = 0;
var_20 = 1.0;
var_21 = 2.0;
}
else if ( isdefined( self.defense_force_next_node_goal ) )
{
self.cur_defend_node = self.defense_force_next_node_goal;
self.defense_force_next_node_goal = undefined;
}
else
self [[ var_16 ]]();
self botclearscriptgoal();
var_23 = "";
if ( isdefined( self.cur_defend_node ) || isdefined( self.cur_defend_point_override ) )
{
if ( var_22 && maps\mp\bots\_bots_util::bot_is_protecting() && !isplayer( var_0 ) && isdefined( self.defend_entrance_index ) )
{
var_24 = bot_get_ambush_trap_item( "trap_directional", "trap", "c4" );
if ( isdefined( var_24 ) )
{
var_25 = maps\mp\bots\_bots_util::bot_get_entrances_for_stance_and_index( undefined, self.defend_entrance_index );
bot_set_ambush_trap( var_24, var_25, self.node_closest_to_defend_center );
}
}
if ( isdefined( self.cur_defend_point_override ) )
{
var_26 = undefined;
if ( isdefined( self.cur_defend_angle_override ) )
var_26 = self.cur_defend_angle_override[1];
self botsetscriptgoal( self.cur_defend_point_override, 0, var_4, var_26 );
}
else if ( !isdefined( self.cur_defend_angle_override ) )
self botsetscriptgoalnode( self.cur_defend_node, var_4 );
else
self botsetscriptgoalnode( self.cur_defend_node, var_4, self.cur_defend_angle_override[1] );
if ( var_17 )
{
if ( !isdefined( self.prev_defend_node ) || !isdefined( self.cur_defend_node ) || self.prev_defend_node != self.cur_defend_node )
self botsetstance( "none" );
}
var_27 = self botgetscriptgoal();
self notify( "new_defend_goal" );
maps\mp\bots\_bots_util::watch_nodes_stop();
if ( var_4 == "objective" )
{
defense_cautious_approach();
self botsetawareness( 1.0 );
self botsetflag( "cautious", 0 );
}
if ( self bothasscriptgoal() )
{
var_28 = self botgetscriptgoal();
if ( maps\mp\bots\_bots_util::bot_vectors_are_equal( var_28, var_27 ) )
var_23 = maps\mp\bots\_bots_util::bot_waittill_goal_or_fail( 20, "defend_force_node_recalculation" );
}
if ( var_23 == "goal" )
{
if ( var_17 )
self botsetstance( self.cur_defend_stance );
childthread defense_watch_entrances_at_goal();
}
}
if ( var_23 != "goal" )
{
wait 0.25;
continue;
}
var_29 = randomfloatrange( var_20, var_21 );
var_23 = common_scripts\utility::waittill_any_timeout( var_29, "node_relinquished", "goal_changed", "script_goal_changed", "defend_force_node_recalculation", "bad_path" );
if ( ( var_23 == "node_relinquished" || var_23 == "bad_path" || var_23 == "goal_changed" || var_23 == "script_goal_changed" ) && ( self.cur_defend_stance == "crouch" || self.cur_defend_stance == "prone" ) )
self botsetstance( "none" );
}
}
calculate_defend_stance( var_0 )
{
var_1 = "stand";
if ( var_0 )
{
var_2 = 100;
var_3 = 0;
var_4 = 0;
var_5 = self botgetdifficultysetting( "strategyLevel" );
if ( var_5 == 1 )
{
var_2 = 20;
var_3 = 25;
var_4 = 55;
}
else if ( var_5 >= 2 )
{
var_2 = 10;
var_3 = 20;
var_4 = 70;
}
var_6 = randomint( 100 );
if ( var_6 < var_3 )
var_1 = "crouch";
else if ( var_6 < var_3 + var_4 )
var_1 = "prone";
if ( var_1 == "prone" )
{
var_7 = bot_defend_get_precalc_entrances_for_current_area( "prone" );
var_8 = defend_get_ally_bots_at_zone_for_stance( "prone" );
if ( var_8.size >= var_7.size )
var_1 = "crouch";
}
if ( var_1 == "crouch" )
{
var_9 = bot_defend_get_precalc_entrances_for_current_area( "crouch" );
var_10 = defend_get_ally_bots_at_zone_for_stance( "crouch" );
if ( var_10.size >= var_9.size )
var_1 = "stand";
}
}
return var_1;
}
should_start_cautious_approach_default( var_0 )
{
var_1 = 1250;
var_2 = var_1 * var_1;
if ( var_0 )
{
if ( self botgetdifficultysetting( "strategyLevel" ) == 0 )
return 0;
if ( self.bot_defending_type == "capture_zone" && self istouching( self.bot_defending_trigger ) )
return 0;
return distancesquared( self.origin, self.bot_defending_center ) > var_2 * 0.75 * 0.75;
}
else if ( self botpursuingscriptgoal() && distancesquared( self.origin, self.bot_defending_center ) < var_2 )
{
var_3 = self botgetpathdist();
return 0 <= var_3 && var_3 <= var_1;
}
else
return 0;
}
setup_investigate_location( var_0, var_1 )
{
var_2 = spawnstruct();
if ( isdefined( var_1 ) )
var_2.origin = var_1;
else
var_2.origin = var_0.origin;
var_2.node = var_0;
var_2.frames_visible = 0;
return var_2;
}
defense_cautious_approach()
{
self notify( "defense_cautious_approach" );
self endon( "defense_cautious_approach" );
level endon( "game_ended" );
self endon( "defend_force_node_recalculation" );
self endon( "death" );
self endon( "disconnect" );
self endon( "defend_stop" );
self endon( "started_bot_defend_think" );
if ( ![[ level.bot_funcs["should_start_cautious_approach"] ]]( 1 ) )
return;
var_0 = self botgetscriptgoal();
var_1 = self botgetscriptgoalnode();
var_2 = 1;
var_3 = 0.2;
while ( var_2 )
{
wait 0.25;
if ( !self bothasscriptgoal() )
return;
var_4 = self botgetscriptgoal();
if ( !maps\mp\bots\_bots_util::bot_vectors_are_equal( var_0, var_4 ) )
return;
var_3 = var_3 + 0.25;
if ( var_3 >= 0.5 )
{
var_3 = 0.0;
if ( [[ level.bot_funcs["should_start_cautious_approach"] ]]( 0 ) )
var_2 = 0;
}
}
self botsetawareness( 1.8 );
self botsetflag( "cautious", 1 );
var_5 = self botgetnodesonpath();
if ( !isdefined( var_5 ) || var_5.size <= 2 )
return;
self.locations_to_investigate = [];
var_6 = 1000;
if ( isdefined( level.protect_radius ) )
var_6 = level.protect_radius;
var_7 = var_6 * var_6;
var_8 = getnodesinradius( self.bot_defending_center, var_6, 0, 500 );
if ( var_8.size <= 0 )
return;
var_9 = 5 + self botgetdifficultysetting( "strategyLevel" ) * 2;
var_10 = int( min( var_9, var_8.size ) );
var_11 = self botnodepickmultiple( var_8, 15, var_10, "node_protect", maps\mp\bots\_bots_util::defend_valid_center(), "ignore_occupancy" );
for ( var_12 = 0; var_12 < var_11.size; var_12++ )
{
var_13 = setup_investigate_location( var_11[var_12] );
self.locations_to_investigate = common_scripts\utility::array_add( self.locations_to_investigate, var_13 );
}
var_14 = botgetmemoryevents( 0, gettime() - 60000, 1, "death", 0, self );
foreach ( var_16 in var_14 )
{
if ( distancesquared( var_16, self.bot_defending_center ) < var_7 )
{
var_17 = getclosestnodeinsight( var_16 );
if ( isdefined( var_17 ) )
{
var_13 = setup_investigate_location( var_17, var_16 );
self.locations_to_investigate = common_scripts\utility::array_add( self.locations_to_investigate, var_13 );
}
}
}
if ( isdefined( self.defend_entrance_index ) )
{
var_19 = maps\mp\bots\_bots_util::bot_get_entrances_for_stance_and_index( "stand", self.defend_entrance_index );
for ( var_12 = 0; var_12 < var_19.size; var_12++ )
{
var_13 = setup_investigate_location( var_19[var_12] );
self.locations_to_investigate = common_scripts\utility::array_add( self.locations_to_investigate, var_13 );
}
}
if ( self.locations_to_investigate.size == 0 )
return;
childthread monitor_cautious_approach_dangerous_locations();
var_20 = self botgetscriptgoaltype();
var_21 = self botgetscriptgoalradius();
var_22 = self botgetscriptgoalyaw();
wait 0.05;
for ( var_23 = 1; var_23 < var_5.size - 2; var_23++ )
{
maps\mp\bots\_bots_util::bot_waittill_out_of_combat_or_time();
var_24 = getlinkednodes( var_5[var_23] );
if ( var_24.size == 0 )
continue;
var_25 = [];
for ( var_12 = 0; var_12 < var_24.size; var_12++ )
{
if ( !common_scripts\utility::within_fov( self.origin, self.angles, var_24[var_12].origin, 0 ) )
continue;
for ( var_26 = 0; var_26 < self.locations_to_investigate.size; var_26++ )
{
var_16 = self.locations_to_investigate[var_26];
if ( nodesvisible( var_16.node, var_24[var_12], 1 ) )
{
var_25 = common_scripts\utility::array_add( var_25, var_24[var_12] );
var_26 = self.locations_to_investigate.size;
}
}
}
if ( var_25.size == 0 )
continue;
var_27 = self botnodepick( var_25, 1 + var_25.size * 0.15, "node_hide" );
if ( isdefined( var_27 ) )
{
var_28 = [];
for ( var_12 = 0; var_12 < self.locations_to_investigate.size; var_12++ )
{
if ( nodesvisible( self.locations_to_investigate[var_12].node, var_27, 1 ) )
var_28 = common_scripts\utility::array_add( var_28, self.locations_to_investigate[var_12] );
}
self botclearscriptgoal();
self botsetscriptgoalnode( var_27, "critical" );
childthread monitor_cautious_approach_early_out();
var_29 = maps\mp\bots\_bots_util::bot_waittill_goal_or_fail( undefined, "cautious_approach_early_out" );
self notify( "stop_cautious_approach_early_out_monitor" );
if ( var_29 == "cautious_approach_early_out" )
break;
if ( var_29 == "goal" )
{
for ( var_12 = 0; var_12 < var_28.size; var_12++ )
{
for ( var_30 = 0; var_28[var_12].frames_visible < 18 && var_30 < 3.6; var_30 = var_30 + 0.25 )
{
self botlookatpoint( var_28[var_12].origin + ( 0, 0, self getplayerviewheight() ), 0.25, "script_search" );
wait 0.25;
}
}
}
}
wait 0.05;
}
self notify( "stop_location_monitoring" );
self botclearscriptgoal();
if ( isdefined( var_1 ) )
self botsetscriptgoalnode( var_1, var_20, var_22 );
else
self botsetscriptgoal( self.cur_defend_point_override, var_21, var_20, var_22 );
}
monitor_cautious_approach_early_out()
{
self endon( "cautious_approach_early_out" );
self endon( "stop_cautious_approach_early_out_monitor" );
var_0 = undefined;
if ( isdefined( self.bot_defending_radius ) )
var_0 = self.bot_defending_radius * self.bot_defending_radius;
else if ( isdefined( self.bot_defending_nodes ) )
{
var_1 = bot_capture_zone_get_furthest_distance();
var_0 = var_1 * var_1;
}
wait 0.05;
for (;;)
{
if ( distancesquared( self.origin, self.bot_defending_center ) < var_0 )
self notify( "cautious_approach_early_out" );
wait 0.05;
}
}
monitor_cautious_approach_dangerous_locations()
{
self endon( "stop_location_monitoring" );
var_0 = 10000;
for (;;)
{
var_1 = self getnearestnode();
if ( isdefined( var_1 ) )
{
var_2 = self botgetfovdot();
for ( var_3 = 0; var_3 < self.locations_to_investigate.size; var_3++ )
{
if ( nodesvisible( var_1, self.locations_to_investigate[var_3].node, 1 ) )
{
var_4 = common_scripts\utility::within_fov( self.origin, self.angles, self.locations_to_investigate[var_3].origin, var_2 );
var_5 = !var_4 || self.locations_to_investigate[var_3].frames_visible < 17;
if ( var_5 && distancesquared( self.origin, self.locations_to_investigate[var_3].origin ) < var_0 )
{
var_4 = 1;
self.locations_to_investigate[var_3].frames_visible = 18;
}
if ( var_4 )
{
self.locations_to_investigate[var_3].frames_visible++;
if ( self.locations_to_investigate[var_3].frames_visible >= 18 )
{
self.locations_to_investigate[var_3] = self.locations_to_investigate[self.locations_to_investigate.size - 1];
self.locations_to_investigate[self.locations_to_investigate.size - 1] = undefined;
var_3--;
}
}
}
}
}
wait 0.05;
}
}
protect_watch_allies()
{
self notify( "protect_watch_allies" );
self endon( "protect_watch_allies" );
var_0 = [];
var_1 = 1050;
var_2 = var_1 * var_1;
var_3 = 900;
if ( isdefined( level.protect_radius ) )
var_3 = level.protect_radius;
for (;;)
{
var_4 = gettime();
var_5 = bot_get_teammates_in_radius( self.bot_defending_center, var_3 );
foreach ( var_7 in var_5 )
{
var_8 = var_7.entity_number;
if ( !isdefined( var_8 ) )
var_8 = var_7 getentitynumber();
if ( !isdefined( var_0[var_8] ) )
var_0[var_8] = var_4 - 1;
if ( !isdefined( var_7.last_investigation_time ) )
var_7.last_investigation_time = var_4 - 10001;
if ( var_7.health == 0 && isdefined( var_7.deathtime ) && var_4 - var_7.deathtime < 5000 )
{
if ( var_4 - var_7.last_investigation_time > 10000 && var_4 > var_0[var_8] )
{
if ( isdefined( var_7.lastattacker ) && isdefined( var_7.lastattacker.team ) && var_7.lastattacker.team == common_scripts\utility::get_enemy_team( self.team ) )
{
if ( distancesquared( var_7.origin, self.origin ) < var_2 )
{
self botgetimperfectenemyinfo( var_7.lastattacker, var_7.origin );
var_9 = getclosestnodeinsight( var_7.origin );
if ( isdefined( var_9 ) )
{
self.defense_investigate_specific_point = var_9.origin;
self notify( "defend_force_node_recalculation" );
}
var_7.last_investigation_time = var_4;
}
var_0[var_8] = var_4 + 10000;
}
}
}
}
wait( ( randomint( 5 ) + 1 ) * 0.05 );
}
}
defense_get_initial_entrances()
{
if ( isdefined( self.defense_override_entrances ) )
return self.defense_override_entrances;
else if ( maps\mp\bots\_bots_util::bot_is_capturing() )
return bot_defend_get_precalc_entrances_for_current_area( self.cur_defend_stance );
else if ( maps\mp\bots\_bots_util::bot_is_protecting() || maps\mp\bots\_bots_util::bot_is_bodyguarding() )
{
var_0 = findentrances( self.origin );
return var_0;
}
}
defense_watch_entrances_at_goal()
{
self notify( "defense_watch_entrances_at_goal" );
self endon( "defense_watch_entrances_at_goal" );
self endon( "new_defend_goal" );
self endon( "script_goal_changed" );
var_0 = self getnearestnode();
var_1 = undefined;
if ( maps\mp\bots\_bots_util::bot_is_capturing() )
{
var_2 = defense_get_initial_entrances();
var_1 = [];
if ( isdefined( var_0 ) )
{
foreach ( var_4 in var_2 )
{
if ( nodesvisible( var_0, var_4, 1 ) )
var_1 = common_scripts\utility::array_add( var_1, var_4 );
}
}
}
else if ( maps\mp\bots\_bots_util::bot_is_protecting() || maps\mp\bots\_bots_util::bot_is_bodyguarding() )
{
var_1 = defense_get_initial_entrances();
if ( isdefined( var_0 ) && !issubstr( self getcurrentweapon(), "riotshield" ) )
{
if ( nodesvisible( var_0, self.node_closest_to_defend_center, 1 ) )
var_1 = common_scripts\utility::array_add( var_1, self.node_closest_to_defend_center );
}
}
if ( isdefined( var_1 ) )
{
childthread maps\mp\bots\_bots_util::bot_watch_nodes( var_1 );
if ( maps\mp\bots\_bots_util::bot_is_bodyguarding() )
childthread bot_monitor_watch_entrances_bodyguard();
else
childthread bot_monitor_watch_entrances_at_goal();
}
}
bot_monitor_watch_entrances_at_goal()
{
self notify( "bot_monitor_watch_entrances_at_goal" );
self endon( "bot_monitor_watch_entrances_at_goal" );
self notify( "bot_monitor_watch_entrances" );
self endon( "bot_monitor_watch_entrances" );
while ( !isdefined( self.watch_nodes ) )
wait 0.05;
var_0 = level.bot_funcs["get_watch_node_chance"];
for (;;)
{
foreach ( var_2 in self.watch_nodes )
{
if ( var_2 == self.node_closest_to_defend_center )
{
var_2.watch_node_chance[self.entity_number] = 0.8;
continue;
}
var_2.watch_node_chance[self.entity_number] = 1.0;
}
var_4 = isdefined( var_0 );
if ( !var_4 )
prioritize_watch_nodes_toward_enemies( 0.5 );
foreach ( var_2 in self.watch_nodes )
{
if ( var_4 )
{
var_6 = self [[ var_0 ]]( var_2 );
var_2.watch_node_chance[self.entity_number] = var_2.watch_node_chance[self.entity_number] * var_6;
}
if ( entrance_watched_by_ally( var_2 ) )
var_2.watch_node_chance[self.entity_number] = var_2.watch_node_chance[self.entity_number] * 0.5;
}
wait( randomfloatrange( 0.5, 0.75 ) );
}
}
bot_monitor_watch_entrances_bodyguard()
{
self notify( "bot_monitor_watch_entrances_bodyguard" );
self endon( "bot_monitor_watch_entrances_bodyguard" );
self notify( "bot_monitor_watch_entrances" );
self endon( "bot_monitor_watch_entrances" );
while ( !isdefined( self.watch_nodes ) )
wait 0.05;
for (;;)
{
var_0 = anglestoforward( self.bot_defend_player_guarding.angles ) * ( 1, 1, 0 );
var_0 = vectornormalize( var_0 );
foreach ( var_2 in self.watch_nodes )
{
var_2.watch_node_chance[self.entity_number] = 1.0;
var_3 = var_2.origin - self.bot_defend_player_guarding.origin;
var_3 = vectornormalize( var_3 );
var_4 = vectordot( var_0, var_3 );
if ( var_4 > 0.6 )
var_2.watch_node_chance[self.entity_number] = var_2.watch_node_chance[self.entity_number] * 0.33;
else if ( var_4 > 0 )
var_2.watch_node_chance[self.entity_number] = var_2.watch_node_chance[self.entity_number] * 0.66;
if ( !entrance_to_enemy_zone( var_2 ) )
var_2.watch_node_chance[self.entity_number] = var_2.watch_node_chance[self.entity_number] * 0.5;
}
wait( randomfloatrange( 0.4, 0.6 ) );
}
}
entrance_to_enemy_zone( var_0 )
{
var_1 = getnodezone( var_0 );
var_2 = vectornormalize( var_0.origin - self.origin );
for ( var_3 = 0; var_3 < level.zonecount; var_3++ )
{
if ( botzonegetcount( var_3, self.team, "enemy_predict" ) > 0 )
{
if ( isdefined( var_1 ) && var_3 == var_1 )
return 1;
else
{
var_4 = vectornormalize( getzoneorigin( var_3 ) - self.origin );
var_5 = vectordot( var_2, var_4 );
if ( var_5 > 0.2 )
return 1;
}
}
}
return 0;
}
prioritize_watch_nodes_toward_enemies( var_0 )
{
if ( self.watch_nodes.size <= 0 )
return;
var_1 = self.watch_nodes;
for ( var_2 = 0; var_2 < level.zonecount; var_2++ )
{
if ( botzonegetcount( var_2, self.team, "enemy_predict" ) <= 0 )
continue;
if ( var_1.size == 0 )
break;
var_3 = vectornormalize( getzoneorigin( var_2 ) - self.origin );
for ( var_4 = 0; var_4 < var_1.size; var_4++ )
{
var_5 = getnodezone( var_1[var_4] );
var_6 = 0;
if ( isdefined( var_5 ) && var_2 == var_5 )
var_6 = 1;
else
{
var_7 = vectornormalize( var_1[var_4].origin - self.origin );
var_8 = vectordot( var_7, var_3 );
if ( var_8 > 0.2 )
var_6 = 1;
}
if ( var_6 )
{
var_1[var_4].watch_node_chance[self.entity_number] = var_1[var_4].watch_node_chance[self.entity_number] * var_0;
var_1[var_4] = var_1[var_1.size - 1];
var_1[var_1.size - 1] = undefined;
var_4--;
}
}
}
}
entrance_watched_by_ally( var_0 )
{
var_1 = bot_get_teammates_currently_defending_point( self.bot_defending_center );
foreach ( var_3 in var_1 )
{
if ( entrance_watched_by_player( var_3, var_0 ) )
return 1;
}
return 0;
}
entrance_watched_by_player( var_0, var_1 )
{
var_2 = anglestoforward( var_0.angles );
var_3 = vectornormalize( var_1.origin - var_0.origin );
var_4 = vectordot( var_2, var_3 );
if ( var_4 > 0.6 )
return 1;
return 0;
}
bot_get_teammates_currently_defending_point( var_0, var_1 )
{
if ( !isdefined( var_1 ) )
{
if ( isdefined( level.protect_radius ) )
var_1 = level.protect_radius;
else
var_1 = 900;
}
var_2 = [];
var_3 = bot_get_teammates_in_radius( var_0, var_1 );
foreach ( var_5 in var_3 )
{
if ( !isai( var_5 ) || var_5 maps\mp\bots\_bots_util::bot_is_defending_point( var_0 ) )
var_2 = common_scripts\utility::array_add( var_2, var_5 );
}
return var_2;
}
bot_get_teammates_in_radius( var_0, var_1 )
{
var_2 = var_1 * var_1;
var_3 = [];
for ( var_4 = 0; var_4 < level.participants.size; var_4++ )
{
var_5 = level.participants[var_4];
if ( var_5 != self && isdefined( var_5.team ) && var_5.team == self.team && maps\mp\_utility::isteamparticipant( var_5 ) )
{
if ( distancesquared( var_0, var_5.origin ) < var_2 )
var_3 = common_scripts\utility::array_add( var_3, var_5 );
}
}
return var_3;
}
defense_death_monitor()
{
level endon( "game_ended" );
self endon( "started_bot_defend_think" );
self endon( "defend_stop" );
self endon( "disconnect" );
self waittill( "death" );
if ( isdefined( self ) )
thread bot_defend_stop();
}
bot_defend_stop()
{
self notify( "defend_stop" );
self.bot_defending = undefined;
self.bot_defending_center = undefined;
self.bot_defending_radius = undefined;
self.bot_defending_nodes = undefined;
self.bot_defending_type = undefined;
self.bot_defending_trigger = undefined;
self.bot_defending_override_origin_node = undefined;
self.bot_defend_player_guarding = undefined;
self.defense_score_flags = undefined;
self.node_closest_to_defend_center = undefined;
self.defense_investigate_specific_point = undefined;
self.defense_force_next_node_goal = undefined;
self.prev_defend_node = undefined;
self.cur_defend_node = undefined;
self.cur_defend_angle_override = undefined;
self.cur_defend_point_override = undefined;
self.defend_entrance_index = undefined;
self.defense_override_entrances = undefined;
self botclearscriptgoal();
self botsetstance( "none" );
}
defend_get_ally_bots_at_zone_for_stance( var_0 )
{
var_1 = [];
foreach ( var_3 in level.participants )
{
if ( !isdefined( var_3.team ) )
continue;
if ( var_3.team == self.team && var_3 != self && isai( var_3 ) && var_3 maps\mp\bots\_bots_util::bot_is_defending() && var_3.cur_defend_stance == var_0 )
{
if ( var_3.bot_defending_type == self.bot_defending_type && maps\mp\bots\_bots_util::bot_is_defending_point( var_3.bot_defending_center ) )
var_1 = common_scripts\utility::array_add( var_1, var_3 );
}
}
return var_1;
}
monitor_defend_player()
{
var_0 = 0;
var_1 = 175;
var_2 = self.bot_defend_player_guarding.origin;
var_3 = 0;
var_4 = 0;
for (;;)
{
if ( !isdefined( self.bot_defend_player_guarding ) )
thread bot_defend_stop();
if ( self.bot_defend_player_guarding islinked() )
{
wait 0.05;
continue;
}
self.bot_defending_center = self.bot_defend_player_guarding.origin;
self.node_closest_to_defend_center = self.bot_defend_player_guarding getnearestnode();
if ( !isdefined( self.node_closest_to_defend_center ) )
self.node_closest_to_defend_center = self getnearestnode();
if ( self botgetscriptgoaltype() != "none" )
{
var_5 = self botgetscriptgoal();
var_6 = self.bot_defend_player_guarding getvelocity();
var_7 = lengthsquared( var_6 );
if ( var_7 > 100 )
{
var_0 = 0;
if ( distancesquared( var_2, self.bot_defend_player_guarding.origin ) > var_1 * var_1 )
{
var_2 = self.bot_defend_player_guarding.origin;
var_4 = 1;
var_8 = vectornormalize( var_5 - self.bot_defend_player_guarding.origin );
var_9 = vectornormalize( var_6 );
if ( vectordot( var_8, var_9 ) < 0.1 )
{
self notify( "defend_force_node_recalculation" );
wait 0.25;
}
}
}
else
{
var_0 = var_0 + 0.05;
if ( var_3 > 100 && var_4 )
{
var_2 = self.bot_defend_player_guarding.origin;
var_4 = 0;
}
if ( var_0 > 0.5 )
{
var_10 = distancesquared( var_5, self.bot_defending_center );
if ( var_10 > self.bot_defending_radius * self.bot_defending_radius )
{
self notify( "defend_force_node_recalculation" );
wait 0.25;
}
}
}
var_3 = var_7;
if ( abs( self.bot_defend_player_guarding.origin[2] - var_5[2] ) >= 50 )
{
self notify( "defend_force_node_recalculation" );
wait 0.25;
}
}
wait 0.05;
}
}
find_defend_node_capture()
{
var_0 = bot_defend_get_random_entrance_point_for_current_area();
var_1 = maps\mp\bots\_bots_util::bot_find_node_to_capture_point( maps\mp\bots\_bots_util::defend_valid_center(), self.bot_defending_radius, var_0 );
if ( isdefined( var_1 ) )
{
if ( isdefined( var_0 ) )
{
var_2 = vectornormalize( var_0 - var_1.origin );
self.cur_defend_angle_override = vectortoangles( var_2 );
}
else
{
var_3 = vectornormalize( var_1.origin - maps\mp\bots\_bots_util::defend_valid_center() );
self.cur_defend_angle_override = vectortoangles( var_3 );
}
self.cur_defend_node = var_1;
}
else if ( isdefined( var_0 ) )
bot_handle_no_valid_defense_node( var_0, undefined );
else
bot_handle_no_valid_defense_node( undefined, maps\mp\bots\_bots_util::defend_valid_center() );
}
find_defend_node_capture_zone()
{
var_0 = bot_defend_get_random_entrance_point_for_current_area();
var_1 = maps\mp\bots\_bots_util::bot_find_node_to_capture_zone( self.bot_defending_nodes, var_0 );
if ( isdefined( var_1 ) )
{
if ( isdefined( var_0 ) )
{
var_2 = vectornormalize( var_0 - var_1.origin );
self.cur_defend_angle_override = vectortoangles( var_2 );
}
else
{
var_3 = vectornormalize( var_1.origin - maps\mp\bots\_bots_util::defend_valid_center() );
self.cur_defend_angle_override = vectortoangles( var_3 );
}
self.cur_defend_node = var_1;
}
else if ( isdefined( var_0 ) )
bot_handle_no_valid_defense_node( var_0, undefined );
else
bot_handle_no_valid_defense_node( undefined, maps\mp\bots\_bots_util::defend_valid_center() );
}
find_defend_node_protect()
{
var_0 = maps\mp\bots\_bots_util::bot_find_node_that_protects_point( maps\mp\bots\_bots_util::defend_valid_center(), self.bot_defending_radius );
if ( isdefined( var_0 ) )
{
var_1 = vectornormalize( maps\mp\bots\_bots_util::defend_valid_center() - var_0.origin );
self.cur_defend_angle_override = vectortoangles( var_1 );
self.cur_defend_node = var_0;
}
else
bot_handle_no_valid_defense_node( maps\mp\bots\_bots_util::defend_valid_center(), undefined );
}
find_defend_node_bodyguard()
{
var_0 = maps\mp\bots\_bots_util::bot_find_node_to_guard_player( maps\mp\bots\_bots_util::defend_valid_center(), self.bot_defending_radius );
if ( isdefined( var_0 ) )
self.cur_defend_node = var_0;
else
{
var_1 = self getnearestnode();
if ( isdefined( var_1 ) )
self.cur_defend_node = var_1;
else
self.cur_defend_point_override = self.origin;
}
}
find_defend_node_patrol()
{
var_0 = undefined;
var_1 = getnodesinradius( maps\mp\bots\_bots_util::defend_valid_center(), self.bot_defending_radius, 0 );
if ( isdefined( var_1 ) && var_1.size > 0 )
var_0 = self botnodepick( var_1, 1 + var_1.size * 0.5, "node_traffic" );
if ( isdefined( var_0 ) )
self.cur_defend_node = var_0;
else
bot_handle_no_valid_defense_node( undefined, maps\mp\bots\_bots_util::defend_valid_center() );
}
bot_handle_no_valid_defense_node( var_0, var_1 )
{
if ( self.bot_defending_type == "capture_zone" )
self.cur_defend_point_override = maps\mp\bots\_bots_util::bot_pick_random_point_from_set( maps\mp\bots\_bots_util::defend_valid_center(), self.bot_defending_nodes, ::bot_can_use_point_in_defend );
else
self.cur_defend_point_override = maps\mp\bots\_bots_util::bot_pick_random_point_in_radius( maps\mp\bots\_bots_util::defend_valid_center(), self.bot_defending_radius, ::bot_can_use_point_in_defend, 0.15, 0.9 );
if ( isdefined( var_0 ) )
{
var_2 = vectornormalize( var_0 - self.cur_defend_point_override );
self.cur_defend_angle_override = vectortoangles( var_2 );
}
else if ( isdefined( var_1 ) )
{
var_2 = vectornormalize( self.cur_defend_point_override - var_1 );
self.cur_defend_angle_override = vectortoangles( var_2 );
}
}
bot_can_use_point_in_defend( var_0 )
{
if ( bot_check_team_is_using_position( var_0, 1, 1, 1 ) )
return 0;
return 1;
}
bot_check_team_is_using_position( var_0, var_1, var_2, var_3 )
{
for ( var_4 = 0; var_4 < level.participants.size; var_4++ )
{
var_5 = level.participants[var_4];
if ( var_5.team == self.team && var_5 != self )
{
if ( isai( var_5 ) )
{
if ( var_2 )
{
if ( distancesquared( var_0, var_5.origin ) < 441 )
return 1;
}
if ( var_3 && var_5 bothasscriptgoal() )
{
var_6 = var_5 botgetscriptgoal();
if ( distancesquared( var_0, var_6 ) < 441 )
return 1;
}
continue;
}
if ( var_1 )
{
if ( distancesquared( var_0, var_5.origin ) < 441 )
return 1;
}
}
}
return 0;
}
bot_capture_zone_get_furthest_distance()
{
var_0 = 0;
if ( isdefined( self.bot_defending_nodes ) )
{
foreach ( var_2 in self.bot_defending_nodes )
{
var_3 = distance( self.bot_defending_center, var_2.origin );
var_0 = max( var_3, var_0 );
}
}
return var_0;
}
bot_think_tactical_goals()
{
self notify( "bot_think_tactical_goals" );
self endon( "bot_think_tactical_goals" );
self endon( "death" );
self endon( "disconnect" );
level endon( "game_ended" );
self.tactical_goals = [];
for (;;)
{
if ( self.tactical_goals.size > 0 && !maps\mp\bots\_bots_util::bot_is_remote_or_linked() )
{
var_0 = self.tactical_goals[0];
if ( !isdefined( var_0.abort ) )
{
self notify( "start_tactical_goal" );
if ( isdefined( var_0.start_thread ) )
self [[ var_0.start_thread ]]( var_0 );
childthread watch_goal_aborted( var_0 );
var_1 = "tactical";
if ( isdefined( var_0.goal_type ) )
var_1 = var_0.goal_type;
self botsetscriptgoal( var_0.goal_position, var_0.goal_radius, var_1, var_0.goal_yaw, var_0.objective_radius );
var_2 = maps\mp\bots\_bots_util::bot_waittill_goal_or_fail( undefined, "stop_tactical_goal" );
self notify( "stop_goal_aborted_watch" );
if ( var_2 == "goal" )
{
if ( isdefined( var_0.action_thread ) )
self [[ var_0.action_thread ]]( var_0 );
}
if ( var_2 != "script_goal_changed" )
self botclearscriptgoal();
if ( isdefined( var_0.end_thread ) )
self [[ var_0.end_thread ]]( var_0 );
}
self.tactical_goals = common_scripts\utility::array_remove( self.tactical_goals, var_0 );
}
wait 0.05;
}
}
watch_goal_aborted( var_0 )
{
self endon( "stop_tactical_goal" );
self endon( "stop_goal_aborted_watch" );
wait 0.05;
for (;;)
{
if ( isdefined( var_0.abort ) || isdefined( var_0.should_abort ) && self [[ var_0.should_abort ]]( var_0 ) )
self notify( "stop_tactical_goal" );
wait 0.05;
}
}
bot_new_tactical_goal( var_0, var_1, var_2, var_3 )
{
var_4 = spawnstruct();
var_4.type = var_0;
var_4.goal_position = var_1;
if ( isdefined( self.only_allowable_tactical_goals ) )
{
if ( !common_scripts\utility::array_contains( self.only_allowable_tactical_goals, var_0 ) )
return;
}
var_4.priority = var_2;
var_4.object = var_3.object;
var_4.goal_type = var_3.script_goal_type;
var_4.goal_yaw = var_3.script_goal_yaw;
var_4.goal_radius = 0;
if ( isdefined( var_3.script_goal_radius ) )
var_4.goal_radius = var_3.script_goal_radius;
var_4.start_thread = var_3.start_thread;
var_4.end_thread = var_3.end_thread;
var_4.should_abort = var_3.should_abort;
var_4.action_thread = var_3.action_thread;
var_4.objective_radius = var_3.objective_radius;
for ( var_5 = 0; var_5 < self.tactical_goals.size; var_5++ )
{
if ( var_4.priority > self.tactical_goals[var_5].priority )
break;
}
for ( var_6 = self.tactical_goals.size - 1; var_6 >= var_5; var_6-- )
self.tactical_goals[var_6 + 1] = self.tactical_goals[var_6];
self.tactical_goals[var_5] = var_4;
}
bot_has_tactical_goal( var_0, var_1 )
{
if ( !isdefined( self.tactical_goals ) )
return 0;
if ( isdefined( var_0 ) )
{
foreach ( var_3 in self.tactical_goals )
{
if ( var_3.type == var_0 )
{
if ( isdefined( var_1 ) && isdefined( var_3.object ) )
return var_3.object == var_1;
else
return 1;
}
}
return 0;
}
else
return self.tactical_goals.size > 0;
}
bot_abort_tactical_goal( var_0, var_1 )
{
if ( !isdefined( self.tactical_goals ) )
return;
foreach ( var_3 in self.tactical_goals )
{
if ( var_3.type == var_0 )
{
if ( isdefined( var_1 ) )
{
if ( isdefined( var_3.object ) && var_3.object == var_1 )
var_3.abort = 1;
continue;
}
var_3.abort = 1;
}
}
}
bot_disable_tactical_goals()
{
self.only_allowable_tactical_goals[0] = "map_interactive_object";
foreach ( var_1 in self.tactical_goals )
{
if ( var_1.type != "map_interactive_object" )
var_1.abort = 1;
}
}
bot_enable_tactical_goals()
{
self.only_allowable_tactical_goals = undefined;
}
bot_melee_tactical_insertion_check()
{
var_0 = gettime();
if ( !isdefined( self.last_melee_ti_check ) || var_0 - self.last_melee_ti_check > 1000 )
{
self.last_melee_ti_check = var_0;
var_1 = bot_get_ambush_trap_item( "tacticalinsertion" );
if ( !isdefined( var_1 ) )
return 0;
if ( isdefined( self.enemy ) && self botcanseeentity( self.enemy ) )
return 0;
var_2 = getzonenearest( self.origin );
if ( !isdefined( var_2 ) )
return 0;
var_3 = botzonenearestcount( var_2, self.team, 1, "enemy_predict", ">", 0 );
if ( !isdefined( var_3 ) )
return 0;
var_4 = getnodesinradius( self.origin, 500, 0 );
if ( var_4.size <= 0 )
return 0;
var_5 = self botnodepick( var_4, var_4.size * 0.15, "node_hide" );
if ( !isdefined( var_5 ) )
return 0;
return bot_set_ambush_trap( var_1, undefined, undefined, undefined, var_5 );
}
return 0;
}