1643 lines
41 KiB
Plaintext
1643 lines
41 KiB
Plaintext
// IW6 GSC SOURCE
|
|
// Generated by https://github.com/xensik/gsc-tool
|
|
|
|
bot_get_nodes_in_cone( var_0, var_1, var_2 )
|
|
{
|
|
var_3 = getnodesinradius( self.origin, var_0, 0 );
|
|
var_4 = [];
|
|
var_5 = self getnearestnode();
|
|
var_6 = anglestoforward( self getplayerangles() );
|
|
var_7 = vectornormalize( var_6 * ( 1, 1, 0 ) );
|
|
|
|
foreach ( var_9 in var_3 )
|
|
{
|
|
var_10 = vectornormalize( ( var_9.origin - self.origin ) * ( 1, 1, 0 ) );
|
|
var_11 = vectordot( var_10, var_7 );
|
|
|
|
if ( var_11 > var_1 )
|
|
{
|
|
if ( !var_2 || isdefined( var_5 ) && nodesvisible( var_9, var_5, 1 ) )
|
|
var_4 = common_scripts\utility::array_add( var_4, var_9 );
|
|
}
|
|
}
|
|
|
|
return var_4;
|
|
}
|
|
|
|
bot_goal_can_override( var_0, var_1 )
|
|
{
|
|
if ( var_0 == "none" )
|
|
return var_1 == "none";
|
|
else if ( var_0 == "hunt" )
|
|
return var_1 == "hunt" || var_1 == "none";
|
|
else if ( var_0 == "guard" )
|
|
return var_1 == "guard" || var_1 == "hunt" || var_1 == "none";
|
|
else if ( var_0 == "objective" )
|
|
return var_1 == "objective" || var_1 == "guard" || var_1 == "hunt" || var_1 == "none";
|
|
else if ( var_0 == "critical" )
|
|
return var_1 == "critical" || var_1 == "objective" || var_1 == "guard" || var_1 == "hunt" || var_1 == "none";
|
|
else if ( var_0 == "tactical" )
|
|
return 1;
|
|
}
|
|
|
|
bot_set_personality( var_0 )
|
|
{
|
|
self botsetpersonality( var_0 );
|
|
maps\mp\bots\_bots_personality::bot_assign_personality_functions();
|
|
self botclearscriptgoal();
|
|
}
|
|
|
|
bot_set_difficulty( var_0 )
|
|
{
|
|
if ( var_0 == "default" )
|
|
var_0 = bot_choose_difficulty_for_default();
|
|
|
|
self botsetdifficulty( var_0 );
|
|
|
|
if ( isplayer( self ) )
|
|
{
|
|
self.pers["rankxp"] = maps\mp\_utility::get_rank_xp_for_bot();
|
|
maps\mp\gametypes\_rank::playerupdaterank();
|
|
}
|
|
}
|
|
|
|
bot_choose_difficulty_for_default()
|
|
{
|
|
if ( !isdefined( level.bot_difficulty_defaults ) )
|
|
{
|
|
level.bot_difficulty_defaults = [];
|
|
level.bot_difficulty_defaults[level.bot_difficulty_defaults.size] = "recruit";
|
|
level.bot_difficulty_defaults[level.bot_difficulty_defaults.size] = "regular";
|
|
level.bot_difficulty_defaults[level.bot_difficulty_defaults.size] = "hardened";
|
|
}
|
|
|
|
var_0 = self.bot_chosen_difficulty;
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
{
|
|
var_1 = [];
|
|
var_2 = self.team;
|
|
|
|
if ( !isdefined( var_2 ) )
|
|
var_2 = self.bot_team;
|
|
|
|
if ( !isdefined( var_2 ) )
|
|
var_2 = self.pers["team"];
|
|
|
|
if ( !isdefined( var_2 ) )
|
|
var_2 = "allies";
|
|
|
|
foreach ( var_4 in level.players )
|
|
{
|
|
if ( var_4 == self )
|
|
continue;
|
|
|
|
if ( !isai( var_4 ) )
|
|
continue;
|
|
|
|
var_5 = var_4 botgetdifficulty();
|
|
|
|
if ( var_5 == "default" )
|
|
continue;
|
|
|
|
var_6 = var_4.team;
|
|
|
|
if ( !isdefined( var_6 ) )
|
|
var_6 = var_4.bot_team;
|
|
|
|
if ( !isdefined( var_6 ) )
|
|
var_6 = var_4.pers["team"];
|
|
|
|
if ( !isdefined( var_6 ) )
|
|
continue;
|
|
|
|
if ( !isdefined( var_1[var_6] ) )
|
|
var_1[var_6] = [];
|
|
|
|
if ( !isdefined( var_1[var_6][var_5] ) )
|
|
{
|
|
var_1[var_6][var_5] = 1;
|
|
continue;
|
|
}
|
|
|
|
var_1[var_6][var_5]++;
|
|
}
|
|
|
|
var_8 = -1;
|
|
|
|
foreach ( var_10 in level.bot_difficulty_defaults )
|
|
{
|
|
if ( !isdefined( var_1[var_2] ) || !isdefined( var_1[var_2][var_10] ) )
|
|
{
|
|
var_0 = var_10;
|
|
break;
|
|
}
|
|
else if ( var_8 == -1 || var_1[var_2][var_10] < var_8 )
|
|
{
|
|
var_8 = var_1[var_2][var_10];
|
|
var_0 = var_10;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( isdefined( var_0 ) )
|
|
self.bot_chosen_difficulty = var_0;
|
|
|
|
return var_0;
|
|
}
|
|
|
|
bot_is_capturing()
|
|
{
|
|
if ( bot_is_defending() )
|
|
{
|
|
if ( self.bot_defending_type == "capture" || self.bot_defending_type == "capture_zone" )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_is_patrolling()
|
|
{
|
|
if ( bot_is_defending() )
|
|
{
|
|
if ( self.bot_defending_type == "patrol" )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_is_protecting()
|
|
{
|
|
if ( bot_is_defending() )
|
|
{
|
|
if ( self.bot_defending_type == "protect" )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_is_bodyguarding()
|
|
{
|
|
if ( bot_is_defending() )
|
|
{
|
|
if ( self.bot_defending_type == "bodyguard" )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_is_defending()
|
|
{
|
|
return isdefined( self.bot_defending );
|
|
}
|
|
|
|
bot_is_defending_point( var_0 )
|
|
{
|
|
if ( bot_is_defending() )
|
|
{
|
|
if ( bot_vectors_are_equal( self.bot_defending_center, var_0 ) )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_is_guarding_player( var_0 )
|
|
{
|
|
if ( bot_is_bodyguarding() && self.bot_defend_player_guarding == var_0 )
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_cache_entrances_to_bombzones()
|
|
{
|
|
var_0 = [];
|
|
var_1 = [];
|
|
var_2 = 0;
|
|
|
|
foreach ( var_4 in level.bombzones )
|
|
{
|
|
var_0[var_2] = common_scripts\utility::random( var_4.bottargets ).origin;
|
|
var_1[var_2] = "zone" + var_4.label;
|
|
var_2++;
|
|
}
|
|
|
|
bot_cache_entrances( var_0, var_1 );
|
|
}
|
|
|
|
bot_cache_entrances_to_flags_or_radios( var_0, var_1 )
|
|
{
|
|
wait 1.0;
|
|
var_2 = [];
|
|
var_3 = [];
|
|
|
|
for ( var_4 = 0; var_4 < var_0.size; var_4++ )
|
|
{
|
|
if ( isdefined( var_0[var_4].bottarget ) )
|
|
var_2[var_4] = var_0[var_4].bottarget.origin;
|
|
else
|
|
{
|
|
var_0[var_4].nearest_node = getclosestnodeinsight( var_0[var_4].origin );
|
|
var_2[var_4] = var_0[var_4].nearest_node.origin;
|
|
}
|
|
|
|
var_3[var_4] = var_1 + var_0[var_4].script_label;
|
|
}
|
|
|
|
bot_cache_entrances( var_2, var_3 );
|
|
}
|
|
|
|
entrance_visible_from( var_0, var_1, var_2 )
|
|
{
|
|
var_3 = ( 0, 0, 11 );
|
|
var_4 = ( 0, 0, 40 );
|
|
var_5 = undefined;
|
|
|
|
if ( var_2 == "stand" )
|
|
return 1;
|
|
else if ( var_2 == "crouch" )
|
|
var_5 = var_4;
|
|
else if ( var_2 == "prone" )
|
|
var_5 = var_3;
|
|
|
|
return sighttracepassed( var_1 + var_5, var_0 + var_5, 0, undefined );
|
|
}
|
|
|
|
bot_cache_entrances( var_0, var_1 )
|
|
{
|
|
wait 0.1;
|
|
var_2 = [];
|
|
|
|
for ( var_3 = 0; var_3 < var_0.size; var_3++ )
|
|
{
|
|
var_4 = var_1[var_3];
|
|
var_2[var_4] = findentrances( var_0[var_3] );
|
|
wait 0.05;
|
|
|
|
for ( var_5 = 0; var_5 < var_2[var_4].size; var_5++ )
|
|
{
|
|
var_6 = var_2[var_4][var_5];
|
|
var_6.is_precalculated_entrance = 1;
|
|
var_6.prone_visible_from[var_4] = entrance_visible_from( var_6.origin, var_0[var_3], "prone" );
|
|
wait 0.05;
|
|
var_6.crouch_visible_from[var_4] = entrance_visible_from( var_6.origin, var_0[var_3], "crouch" );
|
|
wait 0.05;
|
|
|
|
for ( var_7 = 0; var_7 < var_1.size; var_7++ )
|
|
{
|
|
for ( var_8 = var_7 + 1; var_8 < var_1.size; var_8++ )
|
|
{
|
|
var_6.on_path_from[var_1[var_7]][var_1[var_8]] = 0;
|
|
var_6.on_path_from[var_1[var_8]][var_1[var_7]] = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var_9 = [];
|
|
|
|
for ( var_3 = 0; var_3 < var_0.size; var_3++ )
|
|
{
|
|
for ( var_5 = var_3 + 1; var_5 < var_0.size; var_5++ )
|
|
{
|
|
var_10 = get_extended_path( var_0[var_3], var_0[var_5] );
|
|
var_9[var_1[var_3]][var_1[var_5]] = var_10;
|
|
var_9[var_1[var_5]][var_1[var_3]] = var_10;
|
|
|
|
foreach ( var_12 in var_10 )
|
|
{
|
|
var_12.on_path_from[var_1[var_3]][var_1[var_5]] = 1;
|
|
var_12.on_path_from[var_1[var_5]][var_1[var_3]] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !isdefined( level.precalculated_paths ) )
|
|
level.precalculated_paths = [];
|
|
|
|
if ( !isdefined( level.entrance_origin_points ) )
|
|
level.entrance_origin_points = [];
|
|
|
|
if ( !isdefined( level.entrance_indices ) )
|
|
level.entrance_indices = [];
|
|
|
|
if ( !isdefined( level.entrance_points ) )
|
|
level.entrance_points = [];
|
|
|
|
level.precalculated_paths = common_scripts\utility::array_combine_non_integer_indices( level.precalculated_paths, var_9 );
|
|
level.entrance_origin_points = common_scripts\utility::array_combine( level.entrance_origin_points, var_0 );
|
|
level.entrance_indices = common_scripts\utility::array_combine( level.entrance_indices, var_1 );
|
|
level.entrance_points = common_scripts\utility::array_combine_non_integer_indices( level.entrance_points, var_2 );
|
|
level.entrance_points_finished_caching = 1;
|
|
}
|
|
|
|
get_extended_path( var_0, var_1 )
|
|
{
|
|
var_2 = func_get_nodes_on_path( var_0, var_1 );
|
|
|
|
if ( isdefined( var_2 ) )
|
|
{
|
|
var_2 = remove_ends_from_path( var_2 );
|
|
var_2 = get_all_connected_nodes( var_2 );
|
|
}
|
|
|
|
return var_2;
|
|
}
|
|
|
|
func_get_path_dist( var_0, var_1 )
|
|
{
|
|
return getpathdist( var_0, var_1 );
|
|
}
|
|
|
|
func_get_nodes_on_path( var_0, var_1 )
|
|
{
|
|
return getnodesonpath( var_0, var_1 );
|
|
}
|
|
|
|
func_bot_get_closest_navigable_point( var_0, var_1, var_2 )
|
|
{
|
|
return botgetclosestnavigablepoint( var_0, var_1, var_2 );
|
|
}
|
|
|
|
node_is_on_path_from_labels( var_0, var_1 )
|
|
{
|
|
if ( !isdefined( self.on_path_from ) || !isdefined( self.on_path_from[var_0] ) || !isdefined( self.on_path_from[var_0][var_1] ) )
|
|
return 0;
|
|
|
|
return self.on_path_from[var_0][var_1];
|
|
}
|
|
|
|
get_all_connected_nodes( var_0 )
|
|
{
|
|
var_1 = var_0;
|
|
|
|
for ( var_2 = 0; var_2 < var_0.size; var_2++ )
|
|
{
|
|
var_3 = getlinkednodes( var_0[var_2] );
|
|
|
|
for ( var_4 = 0; var_4 < var_3.size; var_4++ )
|
|
{
|
|
if ( !common_scripts\utility::array_contains( var_1, var_3[var_4] ) )
|
|
var_1 = common_scripts\utility::array_add( var_1, var_3[var_4] );
|
|
}
|
|
}
|
|
|
|
return var_1;
|
|
}
|
|
|
|
get_visible_nodes_array( var_0, var_1 )
|
|
{
|
|
var_2 = [];
|
|
|
|
foreach ( var_4 in var_0 )
|
|
{
|
|
if ( nodesvisible( var_4, var_1, 1 ) )
|
|
var_2 = common_scripts\utility::array_add( var_2, var_4 );
|
|
}
|
|
|
|
return var_2;
|
|
}
|
|
|
|
remove_ends_from_path( var_0 )
|
|
{
|
|
var_0[var_0.size - 1] = undefined;
|
|
var_0[0] = undefined;
|
|
return common_scripts\utility::array_removeundefined( var_0 );
|
|
}
|
|
|
|
bot_waittill_bots_enabled( var_0 )
|
|
{
|
|
var_1 = 1;
|
|
|
|
while ( !bot_bots_enabled_or_added( var_0 ) )
|
|
wait 0.5;
|
|
}
|
|
|
|
bot_bots_enabled_or_added( var_0 )
|
|
{
|
|
if ( botautoconnectenabled() )
|
|
return 1;
|
|
|
|
if ( bots_exist( var_0 ) )
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_waittill_out_of_combat_or_time( var_0 )
|
|
{
|
|
var_1 = gettime();
|
|
|
|
for (;;)
|
|
{
|
|
if ( isdefined( var_0 ) )
|
|
{
|
|
if ( gettime() > var_1 + var_0 )
|
|
return;
|
|
}
|
|
|
|
if ( !isdefined( self.enemy ) )
|
|
return;
|
|
else if ( !bot_in_combat() )
|
|
return;
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
bot_in_combat( var_0 )
|
|
{
|
|
var_1 = gettime() - self.last_enemy_sight_time;
|
|
var_2 = level.bot_out_of_combat_time;
|
|
|
|
if ( isdefined( var_0 ) )
|
|
var_2 = var_0;
|
|
|
|
return var_1 < var_2;
|
|
}
|
|
|
|
bot_waittill_goal_or_fail( var_0, var_1, var_2 )
|
|
{
|
|
if ( !isdefined( var_1 ) && isdefined( var_2 ) )
|
|
{
|
|
|
|
}
|
|
|
|
var_3 = [ "goal", "bad_path", "no_path", "node_relinquished", "script_goal_changed" ];
|
|
|
|
if ( isdefined( var_1 ) )
|
|
var_3[var_3.size] = var_1;
|
|
|
|
if ( isdefined( var_2 ) )
|
|
var_3[var_3.size] = var_2;
|
|
|
|
if ( isdefined( var_0 ) )
|
|
var_4 = common_scripts\utility::waittill_any_in_array_or_timeout( var_3, var_0 );
|
|
else
|
|
var_4 = common_scripts\utility::waittill_any_in_array_return( var_3 );
|
|
|
|
return var_4;
|
|
}
|
|
|
|
bot_usebutton_wait( var_0, var_1, var_2 )
|
|
{
|
|
level endon( "game_ended" );
|
|
childthread use_button_stopped_notify();
|
|
var_3 = common_scripts\utility::waittill_any_timeout( var_0, var_1, var_2, "use_button_no_longer_pressed", "finished_use" );
|
|
self notify( "stop_usebutton_watcher" );
|
|
return var_3;
|
|
}
|
|
|
|
use_button_stopped_notify( var_0, var_1 )
|
|
{
|
|
self endon( "stop_usebutton_watcher" );
|
|
wait 0.05;
|
|
|
|
while ( self usebuttonpressed() )
|
|
wait 0.05;
|
|
|
|
self notify( "use_button_no_longer_pressed" );
|
|
}
|
|
|
|
bots_exist( var_0 )
|
|
{
|
|
foreach ( var_2 in level.participants )
|
|
{
|
|
if ( isai( var_2 ) )
|
|
{
|
|
if ( isdefined( var_0 ) && var_0 )
|
|
{
|
|
if ( !maps\mp\_utility::isteamparticipant( var_2 ) )
|
|
continue;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_get_entrances_for_stance_and_index( var_0, var_1 )
|
|
{
|
|
if ( !isdefined( level.entrance_points_finished_caching ) && !isdefined( self.defense_override_entrances ) )
|
|
return undefined;
|
|
|
|
var_2 = [];
|
|
|
|
if ( isdefined( self.defense_override_entrances ) )
|
|
var_2 = self.defense_override_entrances;
|
|
else
|
|
var_2 = level.entrance_points[var_1];
|
|
|
|
if ( !isdefined( var_0 ) || var_0 == "stand" )
|
|
return var_2;
|
|
else if ( var_0 == "crouch" )
|
|
{
|
|
var_3 = [];
|
|
|
|
foreach ( var_5 in var_2 )
|
|
{
|
|
if ( var_5.crouch_visible_from[var_1] )
|
|
var_3 = common_scripts\utility::array_add( var_3, var_5 );
|
|
}
|
|
|
|
return var_3;
|
|
}
|
|
else if ( var_0 == "prone" )
|
|
{
|
|
var_3 = [];
|
|
|
|
foreach ( var_5 in var_2 )
|
|
{
|
|
if ( var_5.prone_visible_from[var_1] )
|
|
var_3 = common_scripts\utility::array_add( var_3, var_5 );
|
|
}
|
|
|
|
return var_3;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
bot_find_node_to_guard_player( var_0, var_1, var_2 )
|
|
{
|
|
var_3 = undefined;
|
|
var_4 = self.bot_defend_player_guarding getvelocity();
|
|
|
|
if ( lengthsquared( var_4 ) > 100 )
|
|
{
|
|
var_5 = getnodesinradius( var_0, var_1 * 1.75, var_1 * 0.5, 500 );
|
|
var_6 = [];
|
|
var_7 = vectornormalize( var_4 );
|
|
|
|
for ( var_8 = 0; var_8 < var_5.size; var_8++ )
|
|
{
|
|
var_9 = vectornormalize( var_5[var_8].origin - self.bot_defend_player_guarding.origin );
|
|
|
|
if ( vectordot( var_9, var_7 ) > 0.1 )
|
|
var_6[var_6.size] = var_5[var_8];
|
|
}
|
|
}
|
|
else
|
|
var_6 = getnodesinradius( var_0, var_1, 0, 500 );
|
|
|
|
if ( isdefined( var_2 ) && var_2 )
|
|
{
|
|
var_10 = vectornormalize( self.bot_defend_player_guarding.origin - self.origin );
|
|
var_11 = var_6;
|
|
var_6 = [];
|
|
|
|
foreach ( var_13 in var_11 )
|
|
{
|
|
var_9 = vectornormalize( var_13.origin - self.bot_defend_player_guarding.origin );
|
|
|
|
if ( vectordot( var_10, var_9 ) > 0.2 )
|
|
var_6[var_6.size] = var_13;
|
|
}
|
|
}
|
|
|
|
var_15 = [];
|
|
var_16 = [];
|
|
var_17 = [];
|
|
|
|
for ( var_8 = 0; var_8 < var_6.size; var_8++ )
|
|
{
|
|
var_18 = distancesquared( var_6[var_8].origin, var_0 ) > 10000;
|
|
var_19 = abs( var_6[var_8].origin[2] - self.bot_defend_player_guarding.origin[2] ) < 50;
|
|
|
|
if ( var_18 )
|
|
var_15[var_15.size] = var_6[var_8];
|
|
|
|
if ( var_19 )
|
|
var_16[var_16.size] = var_6[var_8];
|
|
|
|
if ( var_18 && var_19 )
|
|
var_17[var_17.size] = var_6[var_8];
|
|
|
|
if ( var_8 % 100 == 99 )
|
|
wait 0.05;
|
|
}
|
|
|
|
if ( var_17.size > 0 )
|
|
var_3 = self botnodepick( var_17, var_17.size * 0.15, "node_capture", var_0, undefined, self.defense_score_flags );
|
|
|
|
if ( !isdefined( var_3 ) )
|
|
{
|
|
wait 0.05;
|
|
|
|
if ( var_16.size > 0 )
|
|
var_3 = self botnodepick( var_16, var_16.size * 0.15, "node_capture", var_0, undefined, self.defense_score_flags );
|
|
|
|
if ( !isdefined( var_3 ) && var_15.size > 0 )
|
|
{
|
|
wait 0.05;
|
|
var_3 = self botnodepick( var_15, var_15.size * 0.15, "node_capture", var_0, undefined, self.defense_score_flags );
|
|
}
|
|
}
|
|
|
|
return var_3;
|
|
}
|
|
|
|
bot_find_node_to_capture_point( var_0, var_1, var_2 )
|
|
{
|
|
var_3 = undefined;
|
|
var_4 = getnodesinradius( var_0, var_1, 0, 500 );
|
|
|
|
if ( var_4.size > 0 )
|
|
var_3 = self botnodepick( var_4, var_4.size * 0.15, "node_capture", var_0, var_2, self.defense_score_flags );
|
|
|
|
return var_3;
|
|
}
|
|
|
|
bot_find_node_to_capture_zone( var_0, var_1 )
|
|
{
|
|
var_2 = undefined;
|
|
|
|
if ( var_0.size > 0 )
|
|
var_2 = self botnodepick( var_0, var_0.size * 0.15, "node_capture", undefined, var_1, self.defense_score_flags );
|
|
|
|
return var_2;
|
|
}
|
|
|
|
bot_find_node_that_protects_point( var_0, var_1 )
|
|
{
|
|
var_2 = undefined;
|
|
var_3 = getnodesinradius( var_0, var_1, 0, 500 );
|
|
|
|
if ( var_3.size > 0 )
|
|
var_2 = self botnodepick( var_3, var_3.size * 0.15, "node_protect", var_0, self.defense_score_flags );
|
|
|
|
return var_2;
|
|
}
|
|
|
|
bot_pick_random_point_in_radius( var_0, var_1, var_2, var_3, var_4 )
|
|
{
|
|
var_5 = undefined;
|
|
var_6 = getnodesinradius( var_0, var_1, 0, 500 );
|
|
|
|
if ( isdefined( var_6 ) && var_6.size >= 2 )
|
|
var_5 = bot_find_random_midpoint( var_6, var_2 );
|
|
|
|
if ( !isdefined( var_5 ) )
|
|
{
|
|
if ( !isdefined( var_3 ) )
|
|
var_3 = 0;
|
|
|
|
if ( !isdefined( var_4 ) )
|
|
var_4 = 1;
|
|
|
|
var_7 = randomfloatrange( self.bot_defending_radius * var_3, self.bot_defending_radius * var_4 );
|
|
var_8 = anglestoforward( ( 0, randomint( 360 ), 0 ) );
|
|
var_5 = var_0 + var_8 * var_7;
|
|
}
|
|
|
|
return var_5;
|
|
}
|
|
|
|
bot_pick_random_point_from_set( var_0, var_1, var_2 )
|
|
{
|
|
var_3 = undefined;
|
|
|
|
if ( var_1.size >= 2 )
|
|
var_3 = bot_find_random_midpoint( var_1, var_2 );
|
|
|
|
if ( !isdefined( var_3 ) )
|
|
{
|
|
var_4 = common_scripts\utility::random( var_1 );
|
|
var_5 = var_4.origin - var_0;
|
|
var_3 = var_0 + vectornormalize( var_5 ) * length( var_5 ) * randomfloat( 1.0 );
|
|
}
|
|
|
|
return var_3;
|
|
}
|
|
|
|
bot_find_random_midpoint( var_0, var_1 )
|
|
{
|
|
var_2 = undefined;
|
|
var_3 = common_scripts\utility::array_randomize( var_0 );
|
|
|
|
for ( var_4 = 0; var_4 < var_3.size; var_4++ )
|
|
{
|
|
for ( var_5 = var_4 + 1; var_5 < var_3.size; var_5++ )
|
|
{
|
|
var_6 = var_3[var_4];
|
|
var_7 = var_3[var_5];
|
|
|
|
if ( nodesvisible( var_6, var_7, 1 ) )
|
|
{
|
|
var_2 = ( ( var_6.origin[0] + var_7.origin[0] ) * 0.5, ( var_6.origin[1] + var_7.origin[1] ) * 0.5, ( var_6.origin[2] + var_7.origin[2] ) * 0.5 );
|
|
|
|
if ( isdefined( var_1 ) && self [[ var_1 ]]( var_2 ) == 1 )
|
|
return var_2;
|
|
}
|
|
}
|
|
}
|
|
|
|
return var_2;
|
|
}
|
|
|
|
defend_valid_center()
|
|
{
|
|
if ( isdefined( self.bot_defending_override_origin_node ) )
|
|
return self.bot_defending_override_origin_node.origin;
|
|
else if ( isdefined( self.bot_defending_center ) )
|
|
return self.bot_defending_center;
|
|
|
|
return undefined;
|
|
}
|
|
|
|
bot_allowed_to_use_killstreaks()
|
|
{
|
|
if ( maps\mp\_utility::bot_is_fireteam_mode() )
|
|
{
|
|
if ( isdefined( self.sidelinedbycommander ) && self.sidelinedbycommander == 1 )
|
|
return 0;
|
|
}
|
|
|
|
if ( maps\mp\_utility::iskillstreakdenied() )
|
|
return 0;
|
|
|
|
if ( bot_is_remote_or_linked() )
|
|
return 0;
|
|
|
|
if ( self isusingturret() )
|
|
return 0;
|
|
|
|
if ( isdefined( level.nukeincoming ) )
|
|
return 0;
|
|
|
|
if ( isdefined( self.underwater ) && self.underwater )
|
|
return 0;
|
|
|
|
if ( isdefined( self.controlsfrozen ) && self.controlsfrozen )
|
|
return 0;
|
|
|
|
if ( self isoffhandweaponreadytothrow() )
|
|
return 0;
|
|
|
|
if ( !bot_in_combat( 500 ) )
|
|
return 1;
|
|
|
|
if ( !isalive( self.enemy ) )
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_recent_point_of_interest()
|
|
{
|
|
var_0 = undefined;
|
|
var_1 = botmemoryflags( "investigated", "killer_died" );
|
|
var_2 = botmemoryflags( "investigated" );
|
|
var_3 = common_scripts\utility::random( botgetmemoryevents( 0, gettime() - 10000, 1, "death", var_1, self ) );
|
|
|
|
if ( isdefined( var_3 ) )
|
|
{
|
|
var_0 = var_3;
|
|
self.bot_memory_goal_time = 10000;
|
|
}
|
|
else
|
|
{
|
|
var_4 = undefined;
|
|
|
|
if ( self botgetscriptgoaltype() != "none" )
|
|
var_4 = self botgetscriptgoal();
|
|
|
|
var_5 = botgetmemoryevents( 0, gettime() - 45000, 1, "kill", var_2, self );
|
|
var_6 = botgetmemoryevents( 0, gettime() - 45000, 1, "death", var_1, self );
|
|
var_3 = common_scripts\utility::random( common_scripts\utility::array_combine( var_5, var_6 ) );
|
|
|
|
if ( isdefined( var_3 ) > 0 && ( !isdefined( var_4 ) || distancesquared( var_4, var_3 ) > 1000000 ) )
|
|
{
|
|
var_0 = var_3;
|
|
self.bot_memory_goal_time = 45000;
|
|
}
|
|
}
|
|
|
|
if ( isdefined( var_0 ) )
|
|
{
|
|
var_7 = getzonenearest( var_0 );
|
|
var_8 = getzonenearest( self.origin );
|
|
|
|
if ( isdefined( var_7 ) && isdefined( var_8 ) && var_8 != var_7 )
|
|
{
|
|
var_9 = botzonegetcount( var_7, self.team, "ally" ) + botzonegetcount( var_7, self.team, "path_ally" );
|
|
|
|
if ( var_9 > 1 )
|
|
var_0 = undefined;
|
|
}
|
|
}
|
|
|
|
if ( isdefined( var_0 ) )
|
|
self.bot_memory_goal = var_0;
|
|
|
|
return var_0;
|
|
}
|
|
|
|
bot_draw_cylinder( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 )
|
|
{
|
|
|
|
}
|
|
|
|
bot_draw_cylinder_think( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 )
|
|
{
|
|
|
|
}
|
|
|
|
bot_draw_circle( var_0, var_1, var_2, var_3, var_4 )
|
|
{
|
|
|
|
}
|
|
|
|
bot_get_total_gun_ammo()
|
|
{
|
|
var_0 = 0;
|
|
var_1 = undefined;
|
|
|
|
if ( isdefined( self.weaponlist ) && self.weaponlist.size > 0 )
|
|
var_1 = self.weaponlist;
|
|
else
|
|
var_1 = self getweaponslistprimaries();
|
|
|
|
foreach ( var_3 in var_1 )
|
|
{
|
|
var_0 = var_0 + self getweaponammoclip( var_3 );
|
|
var_0 = var_0 + self getweaponammostock( var_3 );
|
|
}
|
|
|
|
return var_0;
|
|
}
|
|
|
|
bot_out_of_ammo()
|
|
{
|
|
if ( maps\mp\_utility::isjuggernaut() )
|
|
{
|
|
if ( isdefined( self.isjuggernautmaniac ) || isdefined( self.isjuggernautlevelcustom ) )
|
|
{
|
|
if ( self.personality != "run_and_gun" )
|
|
{
|
|
self.prev_personality = self.personality;
|
|
bot_set_personality( "run_and_gun" );
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
var_0 = undefined;
|
|
|
|
if ( isdefined( self.weaponlist ) && self.weaponlist.size > 0 )
|
|
var_0 = self.weaponlist;
|
|
else
|
|
var_0 = self getweaponslistprimaries();
|
|
|
|
foreach ( var_2 in var_0 )
|
|
{
|
|
if ( self getweaponammoclip( var_2 ) > 0 )
|
|
return 0;
|
|
|
|
if ( self getweaponammostock( var_2 ) > 0 )
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
bot_get_grenade_ammo()
|
|
{
|
|
var_0 = 0;
|
|
var_1 = self getweaponslistoffhands();
|
|
|
|
foreach ( var_3 in var_1 )
|
|
var_0 = var_0 + self getweaponammostock( var_3 );
|
|
|
|
return var_0;
|
|
}
|
|
|
|
bot_grenade_matches_purpose( var_0, var_1 )
|
|
{
|
|
if ( !isdefined( var_1 ) )
|
|
return 0;
|
|
|
|
switch ( var_0 )
|
|
{
|
|
case "trap_directional":
|
|
switch ( var_1 )
|
|
{
|
|
case "claymore_mp":
|
|
return 1;
|
|
}
|
|
|
|
break;
|
|
case "trap":
|
|
switch ( var_1 )
|
|
{
|
|
case "proximity_explosive_mp":
|
|
case "motion_sensor_mp":
|
|
case "trophy_mp":
|
|
return 1;
|
|
}
|
|
|
|
break;
|
|
case "c4":
|
|
switch ( var_1 )
|
|
{
|
|
case "c4_mp":
|
|
return 1;
|
|
}
|
|
|
|
break;
|
|
case "tacticalinsertion":
|
|
switch ( var_1 )
|
|
{
|
|
case "flare_mp":
|
|
return 1;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_get_grenade_for_purpose( var_0 )
|
|
{
|
|
if ( self botgetdifficultysetting( "allowGrenades" ) != 0 )
|
|
{
|
|
var_1 = self botfirstavailablegrenade( "lethal" );
|
|
|
|
if ( bot_grenade_matches_purpose( var_0, var_1 ) )
|
|
return "lethal";
|
|
|
|
var_1 = self botfirstavailablegrenade( "tactical" );
|
|
|
|
if ( bot_grenade_matches_purpose( var_0, var_1 ) )
|
|
return "tactical";
|
|
}
|
|
}
|
|
|
|
bot_watch_nodes( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7 )
|
|
{
|
|
self notify( "bot_watch_nodes" );
|
|
self endon( "bot_watch_nodes" );
|
|
self endon( "bot_watch_nodes_stop" );
|
|
self endon( "disconnect" );
|
|
self endon( "death" );
|
|
wait 1.0;
|
|
var_8 = 1;
|
|
|
|
while ( var_8 )
|
|
{
|
|
if ( self bothasscriptgoal() && self botpursuingscriptgoal() )
|
|
{
|
|
if ( distancesquared( self botgetscriptgoal(), self.origin ) < 16 )
|
|
var_8 = 0;
|
|
}
|
|
|
|
if ( var_8 )
|
|
wait 0.05;
|
|
}
|
|
|
|
var_9 = self.origin;
|
|
|
|
if ( isdefined( var_0 ) )
|
|
{
|
|
self.watch_nodes = [];
|
|
|
|
foreach ( var_11 in var_0 )
|
|
{
|
|
var_12 = 0;
|
|
|
|
if ( distance2dsquared( self.origin, var_11.origin ) <= 10 )
|
|
var_12 = 1;
|
|
|
|
var_13 = self geteye();
|
|
var_14 = vectordot( ( 0, 0, 1 ), vectornormalize( var_11.origin - var_13 ) );
|
|
|
|
if ( abs( var_14 ) > 0.92 )
|
|
var_12 = 1;
|
|
|
|
if ( !var_12 )
|
|
self.watch_nodes[self.watch_nodes.size] = var_11;
|
|
}
|
|
}
|
|
|
|
if ( !isdefined( self.watch_nodes ) )
|
|
return;
|
|
|
|
if ( isdefined( var_4 ) )
|
|
self endon( var_4 );
|
|
|
|
if ( isdefined( var_5 ) )
|
|
self endon( var_5 );
|
|
|
|
if ( isdefined( var_6 ) )
|
|
self endon( var_6 );
|
|
|
|
if ( isdefined( var_7 ) )
|
|
self endon( var_7 );
|
|
|
|
thread watch_nodes_aborted();
|
|
self.watch_nodes = common_scripts\utility::array_randomize( self.watch_nodes );
|
|
|
|
foreach ( var_11 in self.watch_nodes )
|
|
var_11.watch_node_chance[self.entity_number] = 1.0;
|
|
|
|
var_18 = gettime();
|
|
var_19 = var_18;
|
|
var_20 = [];
|
|
var_21 = undefined;
|
|
|
|
if ( isdefined( var_1 ) )
|
|
var_21 = ( 0, var_1, 0 );
|
|
|
|
var_22 = isdefined( var_21 ) && isdefined( var_2 );
|
|
var_23 = undefined;
|
|
|
|
for (;;)
|
|
{
|
|
var_24 = gettime();
|
|
self notify( "still_watching_nodes" );
|
|
var_25 = self botgetfovdot();
|
|
|
|
if ( isdefined( var_3 ) && var_24 >= var_3 )
|
|
return;
|
|
|
|
if ( maps\mp\bots\_bots_strategy::bot_has_tactical_goal() )
|
|
{
|
|
self botlookatpoint( undefined );
|
|
wait 0.2;
|
|
continue;
|
|
}
|
|
|
|
if ( !self bothasscriptgoal() || !self botpursuingscriptgoal() )
|
|
{
|
|
wait 0.2;
|
|
continue;
|
|
}
|
|
|
|
if ( isdefined( var_23 ) && var_23.watch_node_chance[self.entity_number] == 0.0 )
|
|
var_19 = var_24;
|
|
|
|
if ( self.watch_nodes.size > 0 )
|
|
{
|
|
var_26 = 0;
|
|
|
|
if ( isdefined( self.enemy ) )
|
|
{
|
|
var_27 = self lastknownpos( self.enemy );
|
|
var_28 = self lastknowntime( self.enemy );
|
|
|
|
if ( var_28 && var_24 - var_28 < 5000 )
|
|
{
|
|
var_29 = vectornormalize( var_27 - self.origin );
|
|
var_30 = 0;
|
|
|
|
for ( var_31 = 0; var_31 < self.watch_nodes.size; var_31++ )
|
|
{
|
|
var_32 = vectornormalize( self.watch_nodes[var_31].origin - self.origin );
|
|
var_33 = vectordot( var_29, var_32 );
|
|
|
|
if ( var_33 > var_30 )
|
|
{
|
|
var_30 = var_33;
|
|
var_23 = self.watch_nodes[var_31];
|
|
var_26 = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( !var_26 && var_24 >= var_19 )
|
|
{
|
|
var_34 = [];
|
|
|
|
for ( var_31 = 0; var_31 < self.watch_nodes.size; var_31++ )
|
|
{
|
|
var_11 = self.watch_nodes[var_31];
|
|
var_35 = var_11 getnodenumber();
|
|
|
|
if ( var_22 && !common_scripts\utility::within_fov( self.origin, var_21, var_11.origin, var_2 ) )
|
|
continue;
|
|
|
|
if ( !isdefined( var_20[var_35] ) )
|
|
var_20[var_35] = 0;
|
|
|
|
if ( common_scripts\utility::within_fov( self.origin, self.angles, var_11.origin, var_25 ) )
|
|
var_20[var_35] = var_24;
|
|
|
|
for ( var_36 = 0; var_36 < var_34.size; var_36++ )
|
|
{
|
|
if ( var_20[var_34[var_36] getnodenumber()] > var_20[var_35] )
|
|
break;
|
|
}
|
|
|
|
var_34 = common_scripts\utility::array_insert( var_34, var_11, var_36 );
|
|
}
|
|
|
|
var_23 = undefined;
|
|
|
|
for ( var_31 = 0; var_31 < var_34.size; var_31++ )
|
|
{
|
|
if ( randomfloat( 1 ) > var_34[var_31].watch_node_chance[self.entity_number] )
|
|
continue;
|
|
|
|
var_23 = var_34[var_31];
|
|
var_19 = var_24 + randomintrange( 3000, 5000 );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( isdefined( var_23 ) )
|
|
{
|
|
var_37 = ( 0, 0, self getplayerviewheight() );
|
|
var_38 = var_23.origin + var_37;
|
|
var_39 = self.origin + ( 0, 0, 55 );
|
|
var_40 = vectornormalize( var_38 - var_39 );
|
|
var_41 = ( 0, 0, 1 );
|
|
|
|
if ( vectordot( var_41, var_40 ) > 0.92 )
|
|
self botlookatpoint( var_38, 0.4, "script_search" );
|
|
}
|
|
}
|
|
|
|
wait 0.2;
|
|
}
|
|
}
|
|
|
|
watch_nodes_stop()
|
|
{
|
|
self notify( "bot_watch_nodes_stop" );
|
|
self.watch_nodes = undefined;
|
|
}
|
|
|
|
watch_nodes_aborted()
|
|
{
|
|
self notify( "watch_nodes_aborted" );
|
|
self endon( "watch_nodes_aborted" );
|
|
|
|
for (;;)
|
|
{
|
|
var_0 = common_scripts\utility::waittill_any_timeout( 0.5, "still_watching_nodes" );
|
|
|
|
if ( !isdefined( var_0 ) || var_0 != "still_watching_nodes" )
|
|
{
|
|
watch_nodes_stop();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bot_leader_dialog( var_0, var_1 )
|
|
{
|
|
if ( isdefined( var_1 ) && var_1 != ( 0, 0, 0 ) )
|
|
{
|
|
if ( !common_scripts\utility::within_fov( self.origin, self.angles, var_1, self botgetfovdot() ) )
|
|
{
|
|
var_2 = self botpredictseepoint( var_1 );
|
|
|
|
if ( isdefined( var_2 ) )
|
|
self botlookatpoint( var_2 + ( 0, 0, 40 ), 1.0, "script_seek" );
|
|
}
|
|
|
|
self botmemoryevent( "known_enemy", undefined, var_1 );
|
|
}
|
|
}
|
|
|
|
bot_get_known_attacker( var_0, var_1 )
|
|
{
|
|
if ( isdefined( var_1 ) && isdefined( var_1.classname ) )
|
|
{
|
|
if ( var_1.classname == "grenade" )
|
|
{
|
|
if ( !bot_ent_is_anonymous_mine( var_1 ) )
|
|
return var_0;
|
|
}
|
|
else if ( var_1.classname == "rocket" )
|
|
{
|
|
if ( isdefined( var_1.vehicle_fired_from ) )
|
|
return var_1.vehicle_fired_from;
|
|
|
|
if ( isdefined( var_1.type ) && ( var_1.type == "remote" || var_1.type == "odin" ) )
|
|
return var_1;
|
|
|
|
if ( isdefined( var_1.owner ) )
|
|
return var_1.owner;
|
|
}
|
|
else if ( var_1.classname == "worldspawn" || var_1.classname == "trigger_hurt" )
|
|
return undefined;
|
|
|
|
return var_1;
|
|
}
|
|
|
|
return var_0;
|
|
}
|
|
|
|
bot_ent_is_anonymous_mine( var_0 )
|
|
{
|
|
if ( !isdefined( var_0.weapon_name ) )
|
|
return 0;
|
|
|
|
if ( var_0.weapon_name == "c4_mp" )
|
|
return 1;
|
|
|
|
if ( var_0.weapon_name == "proximity_explosive_mp" )
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_vectors_are_equal( var_0, var_1 )
|
|
{
|
|
return var_0[0] == var_1[0] && var_0[1] == var_1[1] && var_0[2] == var_1[2];
|
|
}
|
|
|
|
bot_add_to_bot_level_targets( var_0 )
|
|
{
|
|
var_0.high_priority_for = [];
|
|
|
|
if ( var_0.bot_interaction_type == "use" )
|
|
bot_add_to_bot_use_targets( var_0 );
|
|
else if ( var_0.bot_interaction_type == "damage" )
|
|
bot_add_to_bot_damage_targets( var_0 );
|
|
else
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
bot_remove_from_bot_level_targets( var_0 )
|
|
{
|
|
var_0.already_used = 1;
|
|
level.level_specific_bot_targets = common_scripts\utility::array_remove( level.level_specific_bot_targets, var_0 );
|
|
}
|
|
|
|
bot_add_to_bot_use_targets( var_0 )
|
|
{
|
|
if ( !issubstr( var_0.code_classname, "trigger_use" ) )
|
|
return;
|
|
|
|
if ( !isdefined( var_0.target ) )
|
|
return;
|
|
|
|
if ( isdefined( var_0.bot_target ) )
|
|
return;
|
|
|
|
if ( !isdefined( var_0.use_time ) )
|
|
return;
|
|
|
|
var_1 = getnodearray( var_0.target, "targetname" );
|
|
|
|
if ( var_1.size != 1 )
|
|
return;
|
|
|
|
var_0.bot_target = var_1[0];
|
|
|
|
if ( !isdefined( level.level_specific_bot_targets ) )
|
|
level.level_specific_bot_targets = [];
|
|
|
|
level.level_specific_bot_targets = common_scripts\utility::array_add( level.level_specific_bot_targets, var_0 );
|
|
}
|
|
|
|
bot_add_to_bot_damage_targets( var_0 )
|
|
{
|
|
if ( !issubstr( var_0.code_classname, "trigger_damage" ) )
|
|
return;
|
|
|
|
var_1 = getnodearray( var_0.target, "targetname" );
|
|
|
|
if ( var_1.size != 2 )
|
|
return;
|
|
|
|
var_0.bot_targets = var_1;
|
|
|
|
if ( !isdefined( level.level_specific_bot_targets ) )
|
|
level.level_specific_bot_targets = [];
|
|
|
|
level.level_specific_bot_targets = common_scripts\utility::array_add( level.level_specific_bot_targets, var_0 );
|
|
}
|
|
|
|
bot_get_string_index_for_integer( var_0, var_1 )
|
|
{
|
|
var_2 = 0;
|
|
|
|
foreach ( var_5, var_4 in var_0 )
|
|
{
|
|
if ( var_2 == var_1 )
|
|
return var_5;
|
|
|
|
var_2++;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
bot_get_zones_within_dist( var_0, var_1 )
|
|
{
|
|
for ( var_2 = 0; var_2 < level.zonecount; var_2++ )
|
|
{
|
|
var_3 = getzonenodeforindex( var_2 );
|
|
var_3.visited = 0;
|
|
}
|
|
|
|
var_4 = getzonenodeforindex( var_0 );
|
|
return bot_get_zones_within_dist_recurs( var_4, var_1 );
|
|
}
|
|
|
|
bot_get_zones_within_dist_recurs( var_0, var_1 )
|
|
{
|
|
var_2 = [];
|
|
var_2[0] = getnodezone( var_0 );
|
|
var_0.visited = 1;
|
|
var_3 = getlinkednodes( var_0 );
|
|
|
|
foreach ( var_5 in var_3 )
|
|
{
|
|
if ( !var_5.visited )
|
|
{
|
|
var_6 = distance( var_0.origin, var_5.origin );
|
|
|
|
if ( var_6 < var_1 )
|
|
{
|
|
var_7 = bot_get_zones_within_dist_recurs( var_5, var_1 - var_6 );
|
|
var_2 = common_scripts\utility::array_combine( var_7, var_2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
return var_2;
|
|
}
|
|
|
|
bot_crate_is_command_goal( var_0 )
|
|
{
|
|
return isdefined( var_0 ) && isdefined( var_0.command_goal ) && var_0.command_goal;
|
|
}
|
|
|
|
bot_get_team_limit()
|
|
{
|
|
return int( bot_get_client_limit() / 2 );
|
|
}
|
|
|
|
bot_get_client_limit()
|
|
{
|
|
var_0 = getdvarint( "party_maxplayers", 0 );
|
|
var_0 = max( var_0, getdvarint( "party_maxPrivatePartyPlayers", 0 ) );
|
|
|
|
if ( getdvar( "squad_vs_squad" ) == "1" || getdvar( "squad_use_hosts_squad" ) == "1" || getdvar( "squad_match" ) == "1" )
|
|
var_0 = 12;
|
|
|
|
if ( var_0 > level.maxclients )
|
|
return level.maxclients;
|
|
|
|
return var_0;
|
|
}
|
|
|
|
bot_queued_process_level_thread()
|
|
{
|
|
self notify( "bot_queued_process_level_thread" );
|
|
self endon( "bot_queued_process_level_thread" );
|
|
wait 0.05;
|
|
|
|
for (;;)
|
|
{
|
|
if ( isdefined( level.bot_queued_process_queue ) && level.bot_queued_process_queue.size > 0 )
|
|
{
|
|
var_0 = level.bot_queued_process_queue[0];
|
|
|
|
if ( isdefined( var_0 ) && isdefined( var_0.owner ) )
|
|
{
|
|
var_1 = undefined;
|
|
|
|
if ( isdefined( var_0.parm4 ) )
|
|
var_1 = var_0.owner [[ var_0.func ]]( var_0.parm1, var_0.parm2, var_0.parm3, var_0.parm4 );
|
|
else if ( isdefined( var_0.parm3 ) )
|
|
var_1 = var_0.owner [[ var_0.func ]]( var_0.parm1, var_0.parm2, var_0.parm3 );
|
|
else if ( isdefined( var_0.parm2 ) )
|
|
var_1 = var_0.owner [[ var_0.func ]]( var_0.parm1, var_0.parm2 );
|
|
else if ( isdefined( var_0.parm1 ) )
|
|
var_1 = var_0.owner [[ var_0.func ]]( var_0.parm1 );
|
|
else
|
|
var_1 = var_0.owner [[ var_0.func ]]();
|
|
|
|
var_0.owner notify( var_0.name_complete, var_1 );
|
|
}
|
|
|
|
var_2 = [];
|
|
|
|
for ( var_3 = 1; var_3 < level.bot_queued_process_queue.size; var_3++ )
|
|
var_2[var_3 - 1] = level.bot_queued_process_queue[var_3];
|
|
|
|
level.bot_queued_process_queue = var_2;
|
|
}
|
|
|
|
wait 0.05;
|
|
}
|
|
}
|
|
|
|
bot_queued_process( var_0, var_1, var_2, var_3, var_4, var_5 )
|
|
{
|
|
if ( !isdefined( level.bot_queued_process_queue ) )
|
|
level.bot_queued_process_queue = [];
|
|
|
|
foreach ( var_8, var_7 in level.bot_queued_process_queue )
|
|
{
|
|
if ( var_7.owner == self && var_7.name == var_0 )
|
|
{
|
|
self notify( var_7.name );
|
|
level.bot_queued_process_queue[var_8] = undefined;
|
|
}
|
|
}
|
|
|
|
var_7 = spawnstruct();
|
|
var_7.owner = self;
|
|
var_7.name = var_0;
|
|
var_7.name_complete = var_7.name + "_done";
|
|
var_7.func = var_1;
|
|
var_7.parm1 = var_2;
|
|
var_7.parm2 = var_3;
|
|
var_7.parm3 = var_4;
|
|
var_7.parm4 = var_5;
|
|
level.bot_queued_process_queue[level.bot_queued_process_queue.size] = var_7;
|
|
|
|
if ( !isdefined( level.bot_queued_process_level_thread_active ) )
|
|
{
|
|
level.bot_queued_process_level_thread_active = 1;
|
|
level thread bot_queued_process_level_thread();
|
|
}
|
|
|
|
self waittill( var_7.name_complete, var_9 );
|
|
return var_9;
|
|
}
|
|
|
|
bot_is_remote_or_linked()
|
|
{
|
|
return maps\mp\_utility::isusingremote() || self islinked();
|
|
}
|
|
|
|
bot_get_low_on_ammo( var_0 )
|
|
{
|
|
var_1 = undefined;
|
|
|
|
if ( isdefined( self.weaponlist ) && self.weaponlist.size > 0 )
|
|
var_1 = self.weaponlist;
|
|
else
|
|
var_1 = self getweaponslistprimaries();
|
|
|
|
foreach ( var_3 in var_1 )
|
|
{
|
|
var_4 = weaponclipsize( var_3 );
|
|
var_5 = self getweaponammostock( var_3 );
|
|
|
|
if ( var_5 <= var_4 )
|
|
return 1;
|
|
|
|
if ( self getfractionmaxammo( var_3 ) <= var_0 )
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_point_is_on_pathgrid( var_0, var_1, var_2 )
|
|
{
|
|
if ( !isdefined( var_1 ) )
|
|
var_1 = 256;
|
|
|
|
if ( !isdefined( var_2 ) )
|
|
var_2 = 50;
|
|
|
|
var_3 = getnodesinradiussorted( var_0, var_1, 0, var_2, "Path" );
|
|
|
|
foreach ( var_5 in var_3 )
|
|
{
|
|
var_6 = var_0 + ( 0, 0, 30 );
|
|
var_7 = var_5.origin + ( 0, 0, 30 );
|
|
var_8 = physicstrace( var_6, var_7 );
|
|
|
|
if ( bot_vectors_are_equal( var_8, var_7 ) )
|
|
return 1;
|
|
|
|
wait 0.05;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
bot_monitor_enemy_camp_spots( var_0 )
|
|
{
|
|
level endon( "game_ended" );
|
|
self notify( "bot_monitor_enemy_camp_spots" );
|
|
self endon( "bot_monitor_enemy_camp_spots" );
|
|
level.enemy_camp_spots = [];
|
|
level.enemy_camp_assassin_goal = [];
|
|
level.enemy_camp_assassin = [];
|
|
|
|
for (;;)
|
|
{
|
|
wait 1.0;
|
|
var_1 = [];
|
|
|
|
if ( !isdefined( var_0 ) )
|
|
continue;
|
|
|
|
foreach ( var_3 in level.participants )
|
|
{
|
|
if ( !isdefined( var_3.team ) )
|
|
continue;
|
|
|
|
if ( var_3 [[ var_0 ]]() && !isdefined( var_1[var_3.team] ) )
|
|
{
|
|
level.enemy_camp_assassin[var_3.team] = undefined;
|
|
level.enemy_camp_spots[var_3.team] = var_3 botpredictenemycampspots( 1 );
|
|
|
|
if ( isdefined( level.enemy_camp_spots[var_3.team] ) )
|
|
{
|
|
if ( !isdefined( level.enemy_camp_assassin_goal[var_3.team] ) || !common_scripts\utility::array_contains( level.enemy_camp_spots[var_3.team], level.enemy_camp_assassin_goal[var_3.team] ) )
|
|
level.enemy_camp_assassin_goal[var_3.team] = common_scripts\utility::random( level.enemy_camp_spots[var_3.team] );
|
|
|
|
if ( isdefined( level.enemy_camp_assassin_goal[var_3.team] ) )
|
|
{
|
|
var_4 = [];
|
|
|
|
foreach ( var_6 in level.participants )
|
|
{
|
|
if ( !isdefined( var_6.team ) )
|
|
continue;
|
|
|
|
if ( var_6 [[ var_0 ]]() && var_6.team == var_3.team )
|
|
var_4[var_4.size] = var_6;
|
|
}
|
|
|
|
var_4 = sortbydistance( var_4, level.enemy_camp_assassin_goal[var_3.team] );
|
|
|
|
if ( var_4.size > 0 )
|
|
level.enemy_camp_assassin[var_3.team] = var_4[0];
|
|
}
|
|
}
|
|
|
|
var_1[var_3.team] = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bot_valid_camp_assassin()
|
|
{
|
|
if ( !isdefined( self ) )
|
|
return 0;
|
|
|
|
if ( !isai( self ) )
|
|
return 0;
|
|
|
|
if ( !isdefined( self.team ) )
|
|
return 0;
|
|
|
|
if ( self.team == "spectator" )
|
|
return 0;
|
|
|
|
if ( !isalive( self ) )
|
|
return 0;
|
|
|
|
if ( !maps\mp\_utility::isaiteamparticipant( self ) )
|
|
return 0;
|
|
|
|
if ( self.personality == "camper" )
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
bot_update_camp_assassin()
|
|
{
|
|
if ( !isdefined( level.enemy_camp_assassin ) )
|
|
return;
|
|
|
|
if ( !isdefined( level.enemy_camp_assassin[self.team] ) )
|
|
return;
|
|
|
|
if ( level.enemy_camp_assassin[self.team] == self )
|
|
{
|
|
maps\mp\bots\_bots_strategy::bot_defend_stop();
|
|
self botsetscriptgoal( level.enemy_camp_assassin_goal[self.team], 128, "objective", undefined, 256 );
|
|
bot_waittill_goal_or_fail();
|
|
}
|
|
}
|
|
|
|
bot_force_stance_for_time( var_0, var_1 )
|
|
{
|
|
self notify( "bot_force_stance_for_time" );
|
|
self endon( "bot_force_stance_for_time" );
|
|
self endon( "death" );
|
|
self endon( "disconnect" );
|
|
level endon( "game_ended" );
|
|
self botsetstance( var_0 );
|
|
wait( var_1 );
|
|
self botsetstance( "none" );
|
|
}
|