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

2319 lines
63 KiB
Plaintext

// IW6 GSC SOURCE
// Generated by https://github.com/xensik/gsc-tool
init()
{
if ( !isdefined( level.alien_cycle_table ) )
level.alien_cycle_table = "mp/alien/default_cycle_spawn.csv";
if ( !isdefined( level.alien_cycle_table_hardcore ) )
level.alien_cycle_table_hardcore = "mp/alien/default_cycle_spawn_hardcore.csv";
if ( maps\mp\alien\_utility::is_hardcore_mode() )
level.alien_cycle_table = level.alien_cycle_table_hardcore;
if ( !isdefined( level.base_player_count_multiplier ) )
{
level.base_player_count_multiplier = 0.49;
level.additional_player_count_multiplier = 0.17;
}
if ( !isdefined( level.hardcore_spawn_multiplier ) )
level.hardcore_spawn_multiplier = 1.0;
if ( !isdefined( level.hardcore_damage_scalar ) )
level.hardcore_damage_scalar = 1.0;
if ( !isdefined( level.hardcore_health_scalar ) )
level.hardcore_health_scalar = 1.0;
if ( !isdefined( level.hardcore_reward_scalar ) )
level.hardcore_reward_scalar = 1.0;
if ( !isdefined( level.hardcore_score_scalar ) )
level.hardcore_score_scalar = 1.0;
if ( !isdefined( level.casual_spawn_multiplier ) )
level.casual_spawn_multiplier = 1.0;
if ( !isdefined( level.casual_damage_scalar ) )
level.casual_damage_scalar = 0.5;
if ( !isdefined( level.casual_health_scalar ) )
level.casual_health_scalar = 0.5;
if ( !isdefined( level.casual_reward_scalar ) )
level.casual_reward_scalar = 1.0;
if ( !isdefined( level.casual_score_scalar ) )
level.casual_score_scalar = 0.5;
level.cycle_data = spawnstruct();
level.lanes = [];
load_cycles_from_table( level.cycle_data );
init_spawn_node_info( level.cycle_data );
build_spawn_zones( level.cycle_data );
load_spawn_events_from_table( level.cycle_data );
load_variables_from_table( level.cycle_data );
load_cycle_scalars_from_table( level.cycle_data );
load_cycle_drill_layer_from_table( level.cycle_data );
load_random_hives_from_table();
load_encounter_lanes_from_table();
populate_lane_spawners();
level.cycle_data.current_wave_types = create_wave_types_array();
level.cycle_data.current_spawn_event_wave_types = create_wave_types_array();
level thread spawn_type_vo_monitor();
level thread monitor_meteor_spawn();
level thread monitor_ground_spawn();
level.pending_meteor_spawns = 0;
level.pending_ground_spawns = 0;
level.pending_custom_spawns = 0;
level.cycle_spawning_active = 0;
if ( maps\mp\alien\_utility::isplayingsolo() )
level.cycle_data.max_alien_count = int( ceil( 18 * level.base_player_count_multiplier ) );
else
level.cycle_data.max_alien_count = 18;
}
load_variables_from_table( var_0 )
{
var_0.min_spawn_interval = float( tablelookup( level.alien_cycle_table, 0, 400, 2 ) );
var_1 = float( tablelookup( level.alien_cycle_table, 0, 401, 2 ) );
var_0.safe_spawn_distance_sq = var_1 * var_1;
var_0.spawn_point_last_used_duration = float( tablelookup( level.alien_cycle_table, 0, 402, 2 ) ) * 1000.0;
var_2 = float( tablelookup( level.alien_cycle_table, 0, 403, 2 ) );
var_0.group_break_away_distance_sq = var_2 * var_2;
var_0.player_in_zone_score_modifier = float( tablelookup( level.alien_cycle_table, 0, 404, 2 ) );
var_0.current_attacker_in_zone_score_modifier = float( tablelookup( level.alien_cycle_table, 0, 405, 2 ) );
var_0.recently_used_spawn_zone_score_modifier = float( tablelookup( level.alien_cycle_table, 0, 406, 2 ) );
var_0.max_break_away_zone_score_increase = float( tablelookup( level.alien_cycle_table, 0, 407, 2 ) );
var_0.spawn_event_min_activation_time = float( tablelookup( level.alien_cycle_table, 0, 408, 2 ) );
var_0.spawn_event_per_alien_activation_increase = float( tablelookup( level.alien_cycle_table, 0, 409, 2 ) );
var_0.spawn_event_max_activation_increase = float( tablelookup( level.alien_cycle_table, 0, 410, 2 ) );
}
load_encounter_lanes_from_table()
{
level.encounter_lanes = [];
for ( var_0 = 700; var_0 <= 799; var_0++ )
{
var_1 = tablelookup( level.alien_cycle_table, 0, var_0, 1 );
if ( var_1 == "" )
break;
if ( !isdefined( level.encounter_lanes[var_1] ) )
level.encounter_lanes[var_1] = [];
var_2 = strtok( tablelookup( level.alien_cycle_table, 0, var_0, 2 ), ", " );
var_3 = strtok( tablelookup( level.alien_cycle_table, 0, var_0, 3 ), " ,()" );
var_4 = get_lanes_from_names( var_3 );
var_5 = tolower( var_3[0] ) == "random_sequence" && var_3.size > 1;
var_6 = 0;
foreach ( var_8 in var_2 )
{
var_9 = [];
if ( var_5 )
{
var_9[0] = var_4[var_6];
var_6++;
if ( var_6 >= var_4.size )
var_6 = 0;
}
else
var_9 = var_4;
add_new_encounter_lane( var_1, var_9, var_8 );
}
foreach ( var_12 in var_4 )
{
if ( isdefined( level.lanes[var_12] ) )
continue;
level.lanes[var_12] = [];
}
}
foreach ( var_16, var_15 in level.encounter_lanes )
level.encounter_lanes[var_16] = sort_array( level.encounter_lanes[var_16], ::sort_encounter_level_activation_time_func );
}
add_new_encounter_lane( var_0, var_1, var_2 )
{
var_3 = spawnstruct();
var_3.lanes = var_1;
var_3.activation_time = int( var_2 ) * 1000.0;
var_4 = level.encounter_lanes[var_0].size;
level.encounter_lanes[var_0][var_4] = var_3;
}
get_lanes_from_names( var_0 )
{
var_1 = tolower( var_0[0] ) == "random_sequence" && var_0.size > 1;
var_2 = tolower( var_0[0] ) == "random" && var_0.size > 1;
var_3 = [];
if ( var_1 )
{
var_3 = maps\mp\alien\_utility::array_remove_index( var_0, 0 );
var_3 = common_scripts\utility::array_randomize( var_3 );
}
else if ( var_2 )
{
var_4 = randomintrange( 1, var_0.size );
var_3[0] = var_0[var_4];
}
else
var_3 = var_0;
return var_3;
}
populate_lane_spawners()
{
foreach ( var_8, var_1 in level.lanes )
{
var_2 = common_scripts\utility::getstruct( var_8, "targetname" );
var_3 = var_2 common_scripts\utility::get_links();
foreach ( var_5 in var_3 )
{
var_6 = find_spawners_by_script_name( var_5 );
level.lanes[var_8] = common_scripts\utility::array_combine( level.lanes[var_8], var_6 );
}
}
}
find_spawners_by_script_name( var_0 )
{
var_1 = [];
for ( var_2 = 0; var_2 < level.cycle_data.spawner_list.size; var_2++ )
{
if ( !isdefined( level.cycle_data.spawner_list[var_2]["location"].script_linkname ) )
continue;
if ( level.cycle_data.spawner_list[var_2]["location"].script_linkname == var_0 )
var_1[var_1.size] = var_2;
}
return var_1;
}
load_spawn_events_from_table( var_0 )
{
var_0.generic_spawn_events = [];
for ( var_1 = 2000; var_1 <= 2099; var_1++ )
{
var_2 = tablelookup( level.alien_cycle_table, 0, var_1, 1 );
if ( var_2 == "" )
break;
var_3 = int( var_2 ) - 1;
var_4 = spawnstruct();
var_4.activation_notify = tablelookup( level.alien_cycle_table, 0, var_1, 2 );
var_4.id = strtok( tablelookup( level.alien_cycle_table, 0, var_1, 3 ), " ," );
var_4.time_limit = float( tablelookup( level.alien_cycle_table, 0, var_1, 4 ) );
var_5 = strtok( tablelookup( level.alien_cycle_table, 0, var_1, 5 ), " ," );
if ( var_5.size > 0 )
{
var_6 = get_lanes_from_names( var_5 );
var_4.lanes = var_6;
foreach ( var_8 in var_6 )
{
if ( isdefined( level.lanes[var_8] ) )
continue;
level.lanes[var_8] = [];
}
}
if ( var_3 == -1 )
{
var_4.allow_initial_delay = 0;
var_10 = var_0.generic_spawn_events.size;
var_0.generic_spawn_events[var_10] = var_4;
continue;
}
var_4.allow_initial_delay = 1;
var_10 = var_0.spawn_cycles[var_3].spawn_events.size;
var_0.spawn_cycles[var_3].spawn_events[var_10] = var_4;
}
load_spawn_event_waves_from_table();
}
load_spawn_event_waves_from_table()
{
level.spawn_event_waves = [];
for ( var_0 = 3000; var_0 <= 3099; var_0++ )
{
var_1 = tablelookup( level.alien_cycle_table, 0, var_0, 1 );
if ( var_1 == "" )
break;
if ( !isdefined( level.spawn_event_waves[var_1] ) )
level.spawn_event_waves[var_1] = [];
var_2 = spawnstruct();
var_2.blocking = get_spawn_event_wave_blocking_by_index( var_0 );
var_2.spawn_delay = float( tablelookup( level.alien_cycle_table, 0, var_0, 3 ) );
var_2.entry_index = var_0;
var_3 = level.spawn_event_waves[var_1].size;
level.spawn_event_waves[var_1][var_3] = var_2;
}
}
get_spawn_event_wave_blocking_by_index( var_0 )
{
var_1 = tablelookup( level.alien_cycle_table, 0, var_0, 2 );
return var_1 == "yes";
}
clear_spawn_event_wave_types()
{
foreach ( var_1 in level.cycle_data.current_spawn_event_wave_types )
{
var_1.type_name = undefined;
var_1.min_spawned = undefined;
var_1.max_spawned = undefined;
var_1.max_of_type = undefined;
}
}
get_spawn_event_types_array( var_0 )
{
clear_spawn_event_wave_types();
get_type_data( get_available_type_data( level.cycle_data.current_spawn_event_wave_types ), var_0, 4, 5 );
get_type_data( get_available_type_data( level.cycle_data.current_spawn_event_wave_types ), var_0, 6, 7 );
get_type_data( get_available_type_data( level.cycle_data.current_spawn_event_wave_types ), var_0, 8, 9 );
get_type_data( get_available_type_data( level.cycle_data.current_spawn_event_wave_types ), var_0, 10, 11 );
get_type_data( get_available_type_data( level.cycle_data.current_spawn_event_wave_types ), var_0, 12, 13 );
level.cycle_data.current_spawn_event_wave_types = sort_array( level.cycle_data.current_spawn_event_wave_types, ::sort_priority_levels_func );
return level.cycle_data.current_spawn_event_wave_types;
}
set_intensity( var_0 )
{
level.current_intensity = clamp( var_0, 0.0, 1.0 );
}
force_intensity( var_0, var_1 )
{
if ( var_0 )
level.forced_current_intensity = clamp( var_1, 0.0, 1.0 );
else if ( isdefined( level.forced_current_intensity ) )
level.forced_current_intensity = undefined;
}
load_cycles_from_table( var_0 )
{
var_0.spawn_cycles = [];
var_1 = 0;
var_2 = 399;
if ( level.script == "mp_alien_last" && !maps\mp\alien\_utility::is_chaos_mode() )
{
var_1 = 1000;
var_2 = 1999;
}
for ( var_3 = var_1; var_3 <= var_2; var_3++ )
{
var_4 = get_cycle_by_index( var_3 );
if ( var_4 == "" )
break;
var_5 = int( var_4 ) - 1;
if ( !isdefined( var_0.spawn_cycles[var_5] ) )
{
var_6 = spawnstruct();
var_6.intensitylevels = [];
var_6.spawn_events = [];
var_6.lanes = [];
var_6.type_max_counts = [];
var_0.spawn_cycles[var_5] = var_6;
}
else
var_6 = var_0.spawn_cycles[var_5];
var_7 = spawnstruct();
var_7.intensitythreshold = get_intensity_threshold_by_index( var_3 );
var_7.tableindex = var_3;
var_6.intensitylevels[var_6.intensitylevels.size] = var_7;
}
foreach ( var_6 in var_0.spawn_cycles )
{
var_6.intensitylevels = sort_array( var_6.intensitylevels, ::sort_intensity_levels_func );
if ( var_6.intensitylevels.size > 0 )
{
var_9 = var_6.intensitylevels[var_6.intensitylevels.size - 1].intensitythreshold;
foreach ( var_11 in var_6.intensitylevels )
{
if ( var_9 <= 0.0 )
{
var_11.intensitythreshold = 0.0;
continue;
}
var_11.intensitythreshold = var_11.intensitythreshold / var_9;
}
var_6.fullintensitytime = var_9 * 1000.0;
}
}
}
sort_array( var_0, var_1, var_2, var_3 )
{
if ( !isdefined( var_2 ) )
var_2 = 0;
for ( var_4 = var_2 + 1; var_4 < var_0.size; var_4++ )
{
var_5 = var_0[var_4];
for ( var_6 = var_4 - 1; var_6 >= var_2 && [[ var_1 ]]( var_0[var_6], var_5, var_3 ); var_6-- )
var_0[var_6 + 1] = var_0[var_6];
var_0[var_6 + 1] = var_5;
}
return var_0;
}
sort_intensity_levels_func( var_0, var_1, var_2 )
{
return var_0.intensitythreshold > var_1.intensitythreshold;
}
sort_encounter_level_activation_time_func( var_0, var_1, var_2 )
{
return var_0.activation_time > var_1.activation_time;
}
sort_priority_levels_func( var_0, var_1, var_2 )
{
if ( !isdefined( var_1.type_name ) )
return 0;
if ( !isdefined( var_0.type_name ) )
return 1;
var_3 = get_translated_ai_type( var_0.type_name );
var_4 = get_translated_ai_type( var_1.type_name );
var_5 = level.alien_types[var_3].attributes["attacker_priority"];
var_6 = level.alien_types[var_4].attributes["attacker_priority"];
return var_5 > var_6;
}
sort_closest_distance_to_players_func( var_0, var_1, var_2 )
{
var_3 = get_average_distance_to_players( var_0["location"].origin );
var_4 = get_average_distance_to_players( var_1["location"].origin );
return var_3 > var_4;
}
sort_player_view_direction_func( var_0, var_1, var_2 )
{
var_3 = var_2[0];
var_4 = var_2[1];
var_5 = get_player_to_node_dot( var_3, var_4, var_1["location"] );
var_6 = get_player_to_node_dot( var_3, var_4, var_0["location"] );
return var_6 < var_5;
}
get_player_to_node_dot( var_0, var_1, var_2 )
{
var_3 = vectornormalize( var_2.origin - var_0 );
return vectordot( var_3, var_1 );
}
get_average_distance_to_players( var_0 )
{
var_1 = level.players.size;
if ( var_1 == 0 )
return 0;
var_2 = 0;
foreach ( var_4 in level.players )
var_2 = var_2 + distancesquared( var_4.origin, var_0 );
return var_2 / var_1;
}
build_spawn_zones( var_0 )
{
var_1 = common_scripts\utility::getstructarray( "alien_spawn_struct", "targetname" );
var_2 = getentarray( "spawn_zone", "targetname" );
var_0.spawn_zones = [];
foreach ( var_4 in var_2 )
{
var_5 = spawnstruct();
var_5.zone_name = var_4.script_linkname;
var_5.volume = var_4;
var_5.spawn_nodes = [];
var_0.spawn_zones[var_4.script_linkname] = var_5;
}
var_0.spawner_list = [];
put_spawnlocations_into_cycle_data( var_1, var_0 );
}
put_spawnlocations_into_cycle_data( var_0, var_1 )
{
foreach ( var_3 in var_0 )
{
var_4 = [];
if ( isdefined( level.adjust_spawnlocation_func ) )
var_3 = [[ level.adjust_spawnlocation_func ]]( var_3 );
if ( isdefined( var_3.script_noteworthy ) )
var_4 = strtok( var_1.spawn_node_info[var_3.script_noteworthy].validtype, " " );
var_5 = [];
var_5["types"] = var_4;
var_5["location"] = var_3;
var_1.spawner_list[var_1.spawner_list.size] = var_5;
if ( !isdefined( var_3.script_linkto ) )
continue;
var_6 = var_3 common_scripts\utility::get_links();
foreach ( var_8 in var_6 )
{
var_9 = var_1.spawn_zones[var_8].spawn_nodes.size;
var_1.spawn_zones[var_8].spawn_nodes[var_9] = var_5;
}
}
}
spawn_zone_exists( var_0, var_1 )
{
foreach ( var_4, var_3 in var_1.spawn_zones )
{
if ( var_4 == var_0 )
return 1;
}
return 0;
}
can_spawn_type( var_0 )
{
if ( !isdefined( level.current_cycle ) || !isdefined( level.current_cycle.type_max_counts[var_0] ) )
return get_max_alien_count() - get_current_agent_count() > 0;
return level.current_cycle.type_max_counts[var_0] - get_current_agent_count_of_type( var_0 ) > 0;
}
reserve_custom_spawn_space( var_0, var_1, var_2 )
{
if ( !isdefined( var_1 ) )
var_1 = 0;
var_3 = get_current_agent_count();
if ( var_1 )
{
if ( isdefined( var_2 ) && isdefined( level.current_cycle ) && isdefined( level.current_cycle.type_max_counts[var_2] ) )
var_0 = clamp( level.current_cycle.type_max_counts[var_2] - get_current_agent_count_of_type( var_2 ), 0, var_0 );
var_4 = clamp( get_max_alien_count() - var_3, 0, var_0 );
}
else if ( var_3 + var_0 <= get_max_alien_count() )
var_4 = var_0;
else
var_4 = 0;
level.pending_custom_spawns = level.pending_custom_spawns + var_4;
return var_4;
}
process_custom_spawn( var_0, var_1, var_2 )
{
var_3 = get_current_agent_count( 1, 0, 1 );
if ( var_3 >= get_max_alien_count() )
var_4 = undefined;
else
var_4 = process_spawn( var_0, var_1, var_2 );
level.pending_custom_spawns = max( 0, level.pending_custom_spawns - 1 );
return var_4;
}
release_custom_spawn_space( var_0 )
{
level.pending_custom_spawns = max( 0, level.pending_custom_spawns - var_0 );
}
get_cycle_by_index( var_0 )
{
return tablelookup( level.alien_cycle_table, 0, var_0, 1 );
}
get_intensity_level_by_index( var_0 )
{
return tablelookup( level.alien_cycle_table, 0, var_0, 2 );
}
get_respawn_threshold_by_index( var_0 )
{
var_1 = tablelookup( level.alien_cycle_table, 0, var_0, 4 );
if ( var_1 == "" || var_1 == " " )
return undefined;
return int( var_1 );
}
get_respawn_delay_by_index( var_0 )
{
var_1 = tablelookup( level.alien_cycle_table, 0, var_0, 5 );
if ( var_1 == "" || var_1 == " " )
return undefined;
return float( var_1 );
}
get_intensity_threshold_by_index( var_0 )
{
return float( tablelookup( level.alien_cycle_table, 0, var_0, 3 ) );
}
get_types_array( var_0 )
{
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 7, 8 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 9, 10 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 11, 12 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 13, 14 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 15, 16 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 17, 18 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 19, 20 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 21, 22 );
get_type_data( get_available_type_data( level.cycle_data.current_wave_types ), var_0, 23, 24 );
level.cycle_data.current_wave_types = sort_array( level.cycle_data.current_wave_types, ::sort_priority_levels_func );
}
get_available_type_data( var_0 )
{
for ( var_1 = 0; var_1 < var_0.size; var_1++ )
{
if ( !isdefined( var_0[var_1].type_name ) )
return var_0[var_1];
}
return undefined;
}
get_type_data( var_0, var_1, var_2, var_3 )
{
if ( !isdefined( var_0 ) )
return undefined;
var_4 = tablelookup( level.alien_cycle_table, 0, var_1, var_2 );
if ( var_4 == "" )
return undefined;
var_5 = strtok( tablelookup( level.alien_cycle_table, 0, var_1, var_3 ), " " );
var_0.type_name = var_4;
var_5[0] = int( var_5[0] );
var_5[1] = int( var_5[1] );
if ( var_5.size == 0 )
var_0.min_spawned = 0;
else if ( var_5.size == 1 )
var_0.min_spawned = var_5[0];
else
{
if ( var_5[0] < var_5[1] )
{
var_0.min_spawned = var_5[0];
var_0.max_spawned = var_5[1];
}
else if ( var_5[1] > var_5[0] )
{
var_0.min_spawned = var_5[1];
var_0.max_spawned = var_5[0];
}
else
var_0.min_spawned = var_5[0];
if ( var_5.size == 3 )
var_0.max_of_type = int( var_5[2] );
}
return var_0;
}
remove_spawn_location( var_0 )
{
foreach ( var_2 in level.cycle_data.spawn_zones )
{
for ( var_3 = 0; var_3 < var_2.spawn_nodes.size; var_3++ )
{
var_4 = var_2.spawn_nodes[var_3]["location"];
if ( !isdefined( var_4.script_linkname ) )
continue;
if ( var_4.script_linkname == var_0 )
{
var_2.spawn_nodes = maps\mp\alien\_utility::array_remove_index( var_2.spawn_nodes, var_3 );
break;
}
}
}
}
start_cycle( var_0 )
{
set_cycle_scalars( var_0 );
level.cycle_spawning_active = 1;
level thread spawn_director_loop( var_0 - 1 );
level notify( "alien_cycle_started" );
}
end_cycle()
{
level notify( "end_cycle" );
level.cycle_spawning_active = 0;
level notify( "alien_cycle_ended" );
}
pause_cycle( var_0 )
{
if ( !level.cycle_spawning_active )
return;
level thread pause_cycle_internal( var_0 );
}
pause_cycle_internal( var_0 )
{
level.intensity_spawning_paused_count++;
wait( var_0 );
level.intensity_spawning_paused_count = int( max( 0, level.intensity_spawning_paused_count - 1 ) );
}
activate_spawn_event( var_0, var_1 )
{
if ( !isdefined( var_1 ) )
var_1 = 0;
var_2 = find_spawn_event( var_0 );
if ( !isdefined( var_2 ) )
{
if ( isdefined( level.current_cycle_num ) )
var_3 = level.current_cycle_num + 1;
else
var_3 = 0;
}
else
{
if ( var_1 )
{
level run_spawn_event( var_2, var_0 );
return;
}
level thread run_spawn_event( var_2, var_0 );
}
}
find_spawn_event( var_0 )
{
if ( isdefined( level.current_cycle ) )
{
foreach ( var_2 in level.current_cycle.spawn_events )
{
if ( var_2.activation_notify == var_0 )
return var_2;
}
}
foreach ( var_2 in level.cycle_data.generic_spawn_events )
{
if ( var_2.activation_notify == var_0 )
return var_2;
}
return undefined;
}
wait_for_spawn_event_delay()
{
while ( level.pending_meteor_spawns > 0 || level.pending_ground_spawns > 0 )
wait 0.05;
var_0 = level.cycle_data.spawn_event_min_activation_time + level.cycle_data.spawn_event_per_alien_activation_increase * get_current_agent_count();
var_0 = min( level.cycle_data.spawn_event_max_activation_increase, var_0 );
wait( var_0 );
}
run_spawn_event( var_0, var_1 )
{
level endon( "end_cycle" );
level endon( "nuke_went_off" );
level endon( "game_ended" );
if ( level.cycle_spawning_active )
level.intensity_spawning_paused_count++;
if ( var_0.allow_initial_delay )
wait_for_spawn_event_delay();
level thread spawn_event_time_limit_monitor( var_0.time_limit, var_0.activation_notify );
level thread process_spawn_event_spawning( var_0 );
common_scripts\utility::waittill_any( "spawn_event_complete" + var_0.activation_notify, "spawn_event_time_limit_reached" + var_0.activation_notify );
if ( level.cycle_spawning_active )
level.intensity_spawning_paused_count = int( max( 0, level.intensity_spawning_paused_count - 1 ) );
}
process_spawn_event_spawning( var_0 )
{
var_1 = [];
var_2 = randomint( var_0.id.size );
var_3 = var_0.id[var_2];
level.override_lane_index = 0;
foreach ( var_5 in level.spawn_event_waves[var_3] )
{
if ( var_5.spawn_delay > 0.0 )
wait( var_5.spawn_delay );
if ( isdefined( var_0.lanes ) )
var_6 = var_0.lanes;
else
var_6 = undefined;
var_5.types = get_spawn_event_types_array( var_5.entry_index );
if ( wave_has_delayed_spawn_type( var_5 ) )
var_7 = spawn_event_delayed_wave_spawn( var_5, var_0.activation_notify, var_6 );
else
var_7 = spawn_event_wave_spawn( var_5, var_0.activation_notify, var_6 );
var_1 = common_scripts\utility::array_combine( var_1, var_7 );
}
wait_for_all_aliens_killed( var_1, var_0.activation_notify );
level notify( "spawn_event_complete" + var_0.activation_notify );
}
wave_has_delayed_spawn_type( var_0 )
{
if ( wave_has_type( var_0, "minion" ) )
return 1;
if ( wave_has_type( var_0, "elite" ) )
return 1;
return 0;
}
wave_has_type( var_0, var_1 )
{
foreach ( var_3 in var_0.types )
{
if ( !isdefined( var_3.type_name ) )
continue;
if ( var_3.type_name == var_1 )
return 1;
}
return 0;
}
spawn_event_wave_spawn( var_0, var_1, var_2 )
{
var_3 = spawn_wave( var_0.types, "event", var_2 );
if ( var_0.blocking )
spawn_event_wave_block( var_3, var_1 );
return var_3;
}
spawn_event_wave_block( var_0, var_1 )
{
wait_for_all_aliens_killed( var_0, var_1 );
}
spawn_event_delayed_wave_spawn( var_0, var_1, var_2 )
{
var_3 = spawn_wave( var_0.types, "event", var_2 );
if ( level.pending_meteor_spawns > 0 )
level thread spawn_event_minion_wave_spawn();
if ( level.pending_ground_spawns > 0 )
level thread spawn_event_elite_wave_spawn();
while ( level.pending_meteor_spawns > 0 || level.pending_ground_spawns > 0 )
{
level waittill( "spawn_event_delayed_spawn_complete", var_4 );
var_3 = common_scripts\utility::array_combine( var_3, var_4 );
wait 0.05;
}
if ( var_0.blocking )
spawn_event_wave_block( var_3, var_1 );
return var_3;
}
spawn_event_minion_wave_spawn()
{
var_0 = [];
while ( level.pending_meteor_spawns > 0 )
{
level waittill( "meteor_aliens_spawned", var_1, var_2 );
var_0 = common_scripts\utility::array_combine( var_0, var_1 );
wait 0.05;
}
level notify( "spawn_event_delayed_spawn_complete", var_0 );
}
spawn_event_elite_wave_spawn()
{
var_0 = [];
while ( level.pending_ground_spawns > 0 )
{
level waittill( "ground_alien_spawned", var_1 );
var_0[var_0.size] = var_1;
wait 0.05;
}
level notify( "spawn_event_delayed_spawn_complete", var_0 );
}
spawn_event_time_limit_monitor( var_0, var_1 )
{
level endon( "spawn_event_complete" + var_1 );
wait( var_0 );
level notify( "spawn_event_time_limit_reached" + var_1 );
}
wait_for_all_aliens_killed( var_0, var_1 )
{
level endon( "spawn_event_complete" + var_1 );
for (;;)
{
wait 0.05;
var_2 = 0;
foreach ( var_4 in var_0 )
{
if ( isalive( var_4 ) )
{
var_2 = 1;
break;
}
}
if ( !var_2 )
break;
}
}
create_wave_types_array()
{
var_0 = 9;
var_1 = [];
for ( var_2 = 0; var_2 < var_0; var_2++ )
{
var_3 = spawnstruct();
var_3.type_name = undefined;
var_1[var_1.size] = var_3;
}
return var_1;
}
spawn_director_loop( var_0 )
{
level endon( "end_cycle" );
level endon( "nuke_went_off" );
level endon( "game_ended" );
level.spawn_node_traces_this_frame = 0;
level.spawn_node_traces_frame_time = gettime();
level.intensity_spawning_paused_count = 0;
level.current_cycle_num = var_0;
level.current_cycle = level.cycle_data.spawn_cycles[var_0];
cycle_begin_intensity_monitor();
level.pending_meteor_spawns = 0;
level.pending_ground_spawns = 0;
activate_current_lane_monitor();
if ( !isdefined( level.debug_spawn_director_active ) || !level.debug_spawn_director_active )
initial_spawn();
for (;;)
{
var_1 = respawn_threshold_monitor();
respawn( var_1 );
}
}
activate_current_lane_monitor()
{
if ( maps\mp\alien\_utility::is_chaos_mode() )
return;
level thread current_lane_monitor();
}
cycle_begin_intensity_monitor()
{
level.current_intensity_level = -1;
level.current_intensity = 0.0;
level thread intensity_monitor_update_loop();
}
intensity_monitor_update_loop()
{
level endon( "end_cycle" );
level endon( "nuke_went_off" );
level endon( "game_ended" );
var_0 = gettime();
for (;;)
{
var_1 = gettime();
if ( level.intensity_spawning_paused_count == 0 )
{
if ( isdefined( level.forced_current_intensity ) )
level.current_intensity = level.forced_current_intensity;
else if ( level.current_cycle.fullintensitytime == 0.0 )
level.current_intensity = 1.0;
else
{
var_2 = ( var_1 - var_0 ) / level.current_cycle.fullintensitytime;
level.current_intensity = clamp( level.current_intensity + var_2, 0.0, 1.0 );
}
var_0 = var_1;
var_3 = calculate_current_intensity_level();
if ( level.current_intensity_level != var_3 )
level notify( "intensity_level_changed" );
level.current_intensity_level = var_3;
}
else
var_0 = var_1;
wait 0.1;
}
}
current_lane_monitor()
{
level endon( "end_cycle" );
level endon( "nuke_went_off" );
level endon( "game_ended" );
level.cycle_data.current_lane = undefined;
for ( var_0 = get_current_encounter(); !isdefined( var_0 ); var_0 = get_current_encounter() )
wait 0.2;
if ( !isdefined( level.encounter_lanes[var_0] ) || level.encounter_lanes[var_0].size == 0 )
return;
for (;;)
{
var_1 = undefined;
foreach ( var_5, var_3 in level.encounter_lanes[var_0] )
{
var_4 = var_3.activation_time / level.current_cycle.fullintensitytime;
if ( var_4 > level.current_intensity )
break;
var_1 = var_5;
}
if ( isdefined( var_1 ) )
{
var_6 = level.encounter_lanes[var_0][var_1];
if ( !isdefined( level.cycle_data.current_lane ) || var_6 != level.cycle_data.current_lane )
{
level.cycle_data.current_lane = var_6;
play_lane_change_sound();
}
}
wait 0.5;
}
}
play_lane_change_sound()
{
var_0 = get_random_entry( level.cycle_data.current_lane.lanes );
var_1 = level.lanes[var_0][randomint( level.lanes[var_0].size )];
var_2 = level.cycle_data.spawner_list[var_1]["location"].origin;
playsoundatpos( var_2, "alien_distant" );
}
calculate_current_intensity_level()
{
for ( var_0 = 0; var_0 < level.current_cycle.intensitylevels.size; var_0++ )
{
if ( level.current_cycle.intensitylevels[var_0].intensitythreshold > level.current_intensity )
break;
}
return var_0 - 1;
}
initial_spawn()
{
while ( level.current_intensity_level < 0 )
wait 0.05;
var_0 = get_current_wave_ai_types();
spawn_wave( var_0, "spawn" );
}
get_current_wave_ai_types()
{
foreach ( var_1 in level.cycle_data.current_wave_types )
{
var_1.type_name = undefined;
var_1.max_of_type = undefined;
var_1.min_spawned = undefined;
var_1.max_spawned = undefined;
}
var_3 = level.current_cycle.intensitylevels[level.current_intensity_level].tableindex;
get_types_array( var_3 );
level.cycle_data.current_respawn_threshold = get_respawn_threshold_by_index( var_3 );
level.cycle_data.current_respawn_delay = get_respawn_delay_by_index( var_3 );
return level.cycle_data.current_wave_types;
}
respawn( var_0 )
{
if ( isdefined( var_0 ) && var_0 )
{
var_1 = level.cycle_data.current_wave_types;
var_2 = "respawn";
}
else
{
var_1 = get_current_wave_ai_types();
var_2 = "spawn";
}
spawn_wave( var_1, var_2 );
}
spawn_wave( var_0, var_1, var_2 )
{
var_3 = [];
for ( var_4 = 0; var_4 < var_0.size; var_4++ )
{
if ( isdefined( var_0[var_4].type_name ) )
var_3 = common_scripts\utility::array_combine( spawn_type( var_0[var_4], var_1, var_2 ), var_3 );
}
return var_3;
}
respawn_threshold_monitor()
{
level endon( "end cycle" );
level endon( "intensity_level_changed" );
for (;;)
{
if ( level.current_intensity_level >= 0 && level.intensity_spawning_paused_count == 0 )
{
if ( isdefined( level.cycle_data.current_respawn_threshold ) && level.cycle_data.current_respawn_threshold >= 0 )
{
var_0 = get_current_agent_count();
var_1 = get_scaled_alien_amount( level.cycle_data.current_respawn_threshold );
if ( var_0 <= var_1 )
break;
}
}
wait 0.1;
}
if ( isdefined( level.cycle_data.current_respawn_delay ) )
{
if ( level.current_intensity_level >= 0 && level.cycle_data.current_respawn_delay >= 0 )
wait( level.cycle_data.current_respawn_delay * get_current_spawn_count_multiplier() );
}
return 1;
}
get_current_spawn_count_multiplier()
{
var_0 = level.base_player_count_multiplier + level.additional_player_count_multiplier * ( level.players.size - 1 );
if ( maps\mp\alien\_utility::is_hardcore_mode() )
var_0 = var_0 * level.hardcore_spawn_multiplier;
return var_0;
}
spawn_type_vo_monitor()
{
level endon( "game_ended" );
level endon( "nuke_went_off" );
var_0 = gettime();
var_1 = var_0;
var_2 = var_0;
var_3 = 40000;
var_4 = 30000;
for (;;)
{
level waittill( "spawned_alien", var_5 );
if ( !isdefined( var_5.alien_type ) )
continue;
if ( common_scripts\utility::flag_exist( "escape_conditions_met" ) && common_scripts\utility::flag( "escape_conditions_met" ) )
return;
switch ( var_5.alien_type )
{
case "spitter":
var_0 = gettime();
if ( var_0 >= var_1 )
{
level thread maps\mp\alien\_music_and_dialog::playvoforspitterspawn( var_5 );
var_1 = var_0 + var_3;
}
break;
case "elite":
var_0 = gettime();
if ( var_0 >= var_2 )
{
level thread maps\mp\alien\_music_and_dialog::playvoforqueenspawn( var_5 );
var_2 = var_0 + var_4;
}
break;
case "seeder":
level notify( "dlc_vo_notify", "inbound_seeder", var_5 );
break;
case "brute":
level notify( "dlc_vo_notify", "inbound_brute", var_5 );
break;
case "mammoth":
level notify( "dlc_vo_notify", "inbound_mammoth", var_5 );
break;
case "gargoyle":
level notify( "dlc_vo_notify", "inbound_gargoyle", var_5 );
break;
case "bomber":
level notify( "dlc_vo_notify", "inbound_bomber", var_5 );
break;
default:
break;
}
}
}
get_scaled_alien_amount( var_0 )
{
var_1 = var_0 * get_current_spawn_count_multiplier();
return max( 1, int( var_1 + 0.5 ) );
}
get_modified_alien_amount( var_0, var_1, var_2 )
{
var_3 = get_scaled_alien_amount( var_0 );
return get_max_type_count( var_1, var_3 );
}
spawn_type( var_0, var_1, var_2 )
{
if ( !isdefined( var_0.max_spawned ) )
var_3 = var_0.min_spawned;
else
var_3 = randomintrange( var_0.min_spawned, var_0.max_spawned );
var_4 = get_modified_alien_amount( var_3, var_0, var_1 );
var_5 = [];
if ( !isdefined( level.cycle_data.current_lane ) && !isdefined( level.cycle_data.non_lane_spawn_started ) )
{
level thread maps\mp\alien\_music_and_dialog::play2dspawnsound();
level.cycle_data.non_lane_spawn_started = 1;
}
switch ( var_0.type_name )
{
case "minion":
spawn_minions( var_4 );
break;
case "elite":
spawn_elite( var_4 );
break;
default:
var_5 = spawn_aliens( var_4, var_0.type_name, var_2 );
break;
}
return var_5;
}
get_max_alien_count()
{
return level.cycle_data.max_alien_count;
}
get_max_type_count( var_0, var_1 )
{
if ( !isdefined( level.current_cycle ) )
return var_1;
var_2 = get_translated_ai_type( var_0.type_name );
if ( isdefined( var_0.max_of_type ) )
{
if ( var_0.max_of_type <= 0 )
level.current_cycle.type_max_counts[var_2] = undefined;
else
level.current_cycle.type_max_counts[var_2] = var_0.max_of_type;
}
if ( !isdefined( level.current_cycle.type_max_counts[var_2] ) )
return var_1;
var_3 = get_scaled_alien_amount( level.current_cycle.type_max_counts[var_2] );
var_3 = max( 0, var_3 - get_current_agent_count_of_type( var_2 ) );
return min( var_1, var_3 );
}
at_max_alien_count()
{
return get_current_agent_count() >= get_max_alien_count();
}
get_translated_ai_type( var_0 )
{
switch ( var_0 )
{
case "minion_nometeor":
return "minion";
}
return var_0;
}
spawn_aliens( var_0, var_1, var_2 )
{
var_1 = get_translated_ai_type( var_1 );
var_3 = [];
for ( var_4 = 0; var_4 < var_0; var_4++ )
{
if ( at_max_alien_count() )
break;
var_6 = undefined;
if ( maps\mp\alien\_utility::is_chaos_mode() )
var_6 = ::sort_player_view_direction;
var_7 = spawn_alien( var_1, var_2, undefined, var_6 );
var_3[var_3.size] = var_7;
wait( level.cycle_data.min_spawn_interval );
}
return var_3;
}
spawn_minions( var_0 )
{
level thread spawn_meteor_aliens( var_0, "minion" );
wait( level.cycle_data.min_spawn_interval );
}
spawn_elite( var_0 )
{
level thread spawn_ground_aliens( var_0, "elite", ::elite_monitor );
wait( level.cycle_data.min_spawn_interval );
}
elite_monitor()
{
if ( !isdefined( level.cycle_data.elite_count ) || level.cycle_data.elite_count == 0 )
{
level thread maps\mp\alien\_music_and_dialog::handlefirstelitearrival( self );
level.cycle_data.elite_count = 1;
}
else
level.cycle_data.elite_count++;
self waittill( "death" );
level.cycle_data.elite_count--;
if ( level.cycle_data.elite_count == 0 )
level thread maps\mp\alien\_music_and_dialog::handlelastelitedeath( self );
}
is_spawn_debug_info_requested()
{
return getdvarint( "scr_alienspawninfo", 0 ) == 1 || getdvarint( "scr_alienspawneventinfo" ) == 1;
}
spawn_meteor_aliens( var_0, var_1 )
{
level endon( "game_ended" );
level endon( "nuke_went_off" );
if ( var_0 >= 9 )
var_2 = int( var_0 / 3 );
else
var_2 = 4;
level.pending_meteor_spawns = level.pending_meteor_spawns + var_0;
while ( var_0 > 0 )
{
var_3 = var_2;
if ( var_0 < var_2 )
var_3 = var_0;
var_4 = level thread maps\mp\alien\_spawnlogic::spawn_alien_meteoroid( var_1, var_3 );
if ( isdefined( var_4 ) )
{
level.pending_meteor_spawns = level.pending_meteor_spawns - var_0;
return;
}
var_0 = var_0 - var_3;
wait( randomintrange( 5, 10 ) );
level thread maps\mp\alien\_music_and_dialog::playvoforminions();
}
}
spawn_ground_aliens( var_0, var_1, var_2 )
{
level endon( "game_ended" );
level endon( "nuke_went_off" );
var_3 = 2.0;
var_4 = 3.5;
while ( var_0 > 0 )
{
var_5 = level thread spawn_ground_alien( var_1, 1, var_2 );
if ( isdefined( var_5 ) )
return;
level.pending_ground_spawns++;
var_0 = var_0 - 1;
wait( randomfloatrange( var_3, var_4 ) );
}
}
spawn_ground_alien( var_0, var_1, var_2 )
{
var_3 = 10000;
var_4 = [];
var_5 = spawn_alien( var_0, var_4, var_3, ::sort_closest_to_players );
var_5 thread [[ var_2 ]]();
level notify( "ground_alien_spawned", var_5 );
}
monitor_meteor_spawn()
{
level endon( "game_ended" );
level endon( "nuke_went_off" );
for (;;)
{
level waittill( "meteor_aliens_spawned", var_0, var_1 );
level.pending_meteor_spawns = level.pending_meteor_spawns - var_1;
if ( level.pending_meteor_spawns < 0 )
level.pending_meteor_spawns = 0;
}
}
monitor_ground_spawn()
{
level endon( "game_ended" );
level endon( "nuke_went_off" );
for (;;)
{
level waittill( "ground_alien_spawned", var_0 );
var_1 = var_0 maps\mp\alien\_utility::get_alien_type();
if ( !isalive( var_0 ) )
continue;
level.pending_ground_spawns--;
if ( level.pending_ground_spawns < 0 )
level.pending_ground_spawns = 0;
}
}
get_current_agent_count( var_0, var_1, var_2 )
{
var_3 = maps\mp\agents\_agent_utility::getnumactiveagents();
if ( !isdefined( var_0 ) || !var_0 )
var_3 = var_3 + level.pending_meteor_spawns;
if ( !isdefined( var_1 ) || !var_1 )
var_3 = var_3 + level.pending_ground_spawns;
if ( !isdefined( var_2 ) || !var_2 )
var_3 = var_3 + level.pending_custom_spawns;
return var_3;
}
get_current_agent_count_of_type( var_0 )
{
var_1 = maps\mp\agents\_agent_utility::getactiveagentsoftype( "alien" );
var_2 = 0;
foreach ( var_4 in var_1 )
{
if ( isdefined( var_4.pet ) && var_4.pet )
continue;
if ( var_4 maps\mp\alien\_utility::get_alien_type() == var_0 )
var_2++;
}
return var_2;
}
spawn_alien( var_0, var_1, var_2, var_3 )
{
var_4 = find_safe_spawn_point_info( var_0, var_1, var_2, var_3 );
var_5 = var_4["node"];
var_6 = 0;
if ( var_0 == "spitter" && isdefined( level.hive_heli ) && level.hive_heli.health > 0 && threatbiasgroupexists( "spitters" ) )
{
var_7 = 0;
var_8 = 0;
foreach ( var_10 in level.agentarray )
{
if ( !isdefined( var_10.isactive ) || !var_10.isactive || !isalive( var_10 ) || !isdefined( var_10.alien_type ) || var_10.alien_type != "spitter" )
continue;
if ( var_10 getthreatbiasgroup() == "spitters" )
{
var_8++;
continue;
}
var_7++;
}
var_12 = int( max( 1, var_8 + var_7 ) );
level.spitters_against_players_ratio = var_7 / var_12;
var_13 = 0;
foreach ( var_15 in level.players )
var_13 = var_13 + distance2d( var_15.origin, level.hive_heli.origin );
var_17 = var_13 / int( min( 1, level.players.size ) );
var_18 = 0.32;
if ( var_17 > 1500 )
var_18 = 0.1;
if ( level.spitters_against_players_ratio >= var_18 )
var_6 = 1;
}
var_19 = process_intro_vignette_ai_type( var_0 );
if ( isdefined( var_5.script_noteworthy ) )
var_20 = level.cycle_data.spawn_node_info[var_5.script_noteworthy].vignetteinfo[var_19];
else
var_20 = undefined;
var_21 = process_spawn( var_0, var_5, var_20 );
if ( ( var_0 == "spitter" || var_0 == "seeder" ) && isdefined( level.hive_heli ) && level.hive_heli.health > 0 && threatbiasgroupexists( "spitters" ) )
{
if ( var_6 )
var_21 maps\mp\alien\_spawnlogic::make_spitter_attack_chopper( 1 );
else
var_21 maps\mp\alien\_spawnlogic::make_spitter_attack_chopper( 0 );
}
if ( ( var_0 == "spitter" || var_0 == "seeder" || var_0 == "gargoyle" ) && common_scripts\utility::flag_exist( "player_using_vanguard" ) && common_scripts\utility::flag( "player_using_vanguard" ) && threatbiasgroupexists( "spitters" ) )
{
var_21 setthreatbiasgroup( "spitters" );
var_21.favoriteenemy = level.alien_vanguard;
}
if ( isdefined( var_5.script_noteworthy ) )
{
if ( issubstr( var_5.script_noteworthy, "vent" ) )
level notify( "dlc_vo_notify", "direction_vo", "spawn_vent" );
if ( issubstr( var_5.script_noteworthy, "duct" ) )
level notify( "dlc_vo_notify", "direction_vo", "spawn_vent" );
if ( issubstr( var_5.script_noteworthy, "grate" ) )
level notify( "dlc_vo_notify", "direction_vo", "spawn_grate" );
}
level notify( "spawned_alien", var_21 );
return var_21;
}
process_intro_vignette_ai_type( var_0 )
{
switch ( var_0 )
{
case "leper":
case "locust":
return "brute";
case "mammoth":
return "elite";
}
return var_0;
}
process_spawn( var_0, var_1, var_2 )
{
var_3 = ( 0, 0, 0 );
if ( isdefined( var_1.angles ) )
var_3 = var_1.angles;
var_1.last_used_time = gettime();
var_4 = "wave " + var_0;
var_5 = maps\mp\gametypes\aliens::addalienagent( "axis", var_1.origin, var_3, var_4, var_2 );
return var_5;
}
find_safe_spawn_point_info( var_0, var_1, var_2, var_3 )
{
if ( should_lane_spawn( var_1, var_0 ) )
return find_lane_spawn_node( var_1 );
var_4 = get_current_player_volumes();
if ( var_4.size == 0 )
{
var_5 = find_random_spawn_node( level.cycle_data.spawner_list, var_0, var_2, ::filter_spawn_point_by_distance_from_player, undefined, var_3 );
return var_5;
}
else if ( var_4.size == 1 )
{
foreach ( var_8, var_7 in var_4 )
{
if ( level.cycle_data.spawn_zones[var_8].spawn_nodes.size == 0 )
continue;
var_5 = find_random_spawn_node( level.cycle_data.spawn_zones[var_8].spawn_nodes, var_0, var_2, undefined, undefined, var_3 );
return var_5;
}
}
return find_safe_spawn_spot_with_volumes( var_4, var_0, var_2, var_3 );
}
get_current_encounter()
{
return level.encounter_name;
}
should_lane_spawn( var_0, var_1 )
{
var_2 = 1024;
if ( maps\mp\alien\_utility::is_chaos_mode() )
return 0;
if ( isdefined( var_0 ) && var_0.size == 0 )
return 0;
if ( !can_spawn_at_any_node( var_1 ) )
return 0;
if ( isdefined( level.blocker_hive_active ) && level.blocker_hive_active )
return 1;
var_3 = get_current_drill_state();
if ( !isdefined( var_0 ) )
{
if ( !isdefined( level.cycle_data.current_lane ) )
return 0;
if ( var_3 == "idle" )
return 0;
}
if ( var_3 == "offline" )
{
var_4 = 0;
var_5 = 0;
foreach ( var_7 in level.players )
{
if ( isdefined( var_7 ) && isalive( var_7 ) )
{
var_5++;
var_4 = var_4 + distance2d( var_7.origin, level.drill.origin );
}
}
if ( var_5 > 0 )
{
if ( var_4 / var_5 > var_2 )
return 0;
}
}
return 1;
}
get_current_drill_state()
{
if ( !isdefined( level.drill ) || !isdefined( level.drill.state ) )
return "undefined";
return level.drill.state;
}
get_override_lane_entry( var_0 )
{
if ( !isdefined( level.override_lane_index ) )
return get_random_entry( var_0 );
if ( level.override_lane_index >= var_0.size )
level.override_lane_index = 0;
var_1 = level.override_lane_index;
level.override_lane_index++;
return var_0[var_1];
}
find_lane_spawn_node( var_0 )
{
if ( isdefined( var_0 ) && var_0.size > 0 )
{
var_1 = get_random_entry( var_0 );
var_2 = get_override_lane_entry( level.lanes[var_1] );
}
else
{
var_1 = get_random_entry( level.cycle_data.current_lane.lanes );
var_2 = level.lanes[var_1][randomint( level.lanes[var_1].size )];
}
var_3 = [];
var_3["node"] = level.cycle_data.spawner_list[var_2]["location"];
var_3["validNode"] = 1;
return var_3;
}
get_current_encounter_lane_index()
{
var_0 = undefined;
var_1 = get_current_encounter();
if ( !isdefined( var_1 ) )
return undefined;
foreach ( var_5, var_3 in level.encounter_lanes[var_1] )
{
var_4 = var_3.activation_time / level.current_cycle.fullintensitytime;
if ( var_4 > level.current_intensity )
break;
var_0 = var_5;
}
return level.encounter_lanes[var_1][var_0];
}
get_random_entry( var_0 )
{
var_1 = -1;
var_2 = randomint( var_0.size );
foreach ( var_5, var_4 in var_0 )
{
var_1++;
if ( var_1 == var_2 )
return var_0[var_5];
}
return undefined;
}
filter_spawn_point_by_distance_from_player( var_0, var_1 )
{
if ( var_1 == "elite" )
return 1;
var_2 = level.players[0].origin;
return distancesquared( var_2, var_0.origin ) > level.cycle_data.safe_spawn_distance_sq;
}
sort_closest_to_players( var_0 )
{
return sort_array( var_0, ::sort_closest_distance_to_players_func, 0 );
}
sort_player_view_direction( var_0 )
{
var_1 = level.players[randomint( level.players.size )];
var_2 = anglestoforward( var_1 getplayerangles() );
return sort_array( var_0, ::sort_player_view_direction_func, 0, [ var_1.origin, var_2 ] );
}
find_random_spawn_node( var_0, var_1, var_2, var_3, var_4, var_5 )
{
if ( isdefined( var_2 ) )
var_6 = var_2;
else
var_6 = level.cycle_data.spawn_point_last_used_duration;
if ( !isdefined( var_5 ) )
var_5 = common_scripts\utility::array_randomize;
var_0 = [[ var_5 ]]( var_0 );
var_7 = 0;
var_8 = randomfloatrange( var_6 * 0.5, var_6 * 0.75 );
var_9 = 0.0;
var_10 = 0;
for ( var_11 = 0; var_11 < var_0.size; var_11++ )
{
var_12 = var_0[var_11]["location"];
if ( isdefined( var_3 ) && !passes_spawn_node_filter( var_12, var_1, var_3, var_4 ) )
continue;
if ( isdefined( var_0[var_11]["location"].script_linkname ) )
var_13 = var_0[var_11]["location"].script_linkname;
else
var_13 = undefined;
if ( !is_valid_spawn_node_for_type( var_0[var_11]["types"], var_1, var_13 ) )
continue;
if ( !isdefined( var_12.last_used_time ) )
{
var_10 = 1;
var_7 = var_11;
break;
}
var_14 = gettime() - var_12.last_used_time;
if ( var_14 > var_8 )
{
var_10 = 1;
var_7 = var_11;
break;
}
if ( var_14 > var_9 )
{
var_9 = var_14;
var_7 = var_11;
}
}
var_15 = [];
var_15["node"] = var_0[var_7]["location"];
var_15["validNode"] = var_10;
return var_15;
}
is_valid_spawn_node_for_type( var_0, var_1, var_2 )
{
if ( var_0.size == 0 )
return can_spawn_at_any_node( var_1 );
foreach ( var_4 in var_0 )
{
if ( var_4 == var_1 )
return 1;
}
return 0;
}
can_spawn_at_any_node( var_0 )
{
if ( isdefined( level.dlc_alien_type_node_match_override_func ) )
{
var_1 = self [[ level.dlc_alien_type_node_match_override_func ]]( var_0 );
if ( isdefined( var_1 ) )
return var_1;
}
switch ( var_0 )
{
case "elite":
return 0;
default:
return 1;
}
}
passes_spawn_node_filter( var_0, var_1, var_2, var_3 )
{
if ( isdefined( var_3 ) )
return [[ var_2 ]]( var_0, var_1, var_3 );
return [[ var_2 ]]( var_0, var_1 );
}
find_safe_spawn_spot_with_volumes( var_0, var_1, var_2, var_3 )
{
var_4 = score_and_sort_spawn_zones( var_0 );
foreach ( var_6 in var_4 )
{
if ( level.cycle_data.spawn_zones[var_6.name].spawn_nodes.size == 0 )
continue;
var_7 = [];
foreach ( var_10, var_9 in var_0 )
{
if ( var_10 != var_6.name )
var_7 = common_scripts\utility::array_combine( var_7, var_9.players );
}
var_11 = find_random_spawn_node( level.cycle_data.spawn_zones[var_6.name].spawn_nodes, var_1, var_2, ::is_safe_spawn_location, var_7, var_3 );
if ( var_11["validNode"] )
return var_11;
}
var_11 = find_random_spawn_node( level.cycle_data.spawner_list, var_1, var_2, ::filter_spawn_point_by_distance_from_player, undefined, var_3 );
return var_11;
}
score_and_sort_spawn_zones( var_0 )
{
var_1 = calculate_player_proximity_scores();
foreach ( var_3 in var_0 )
{
var_4 = 0.0;
foreach ( var_6 in var_3.players )
{
var_4 = var_4 + level.cycle_data.player_in_zone_score_modifier;
if ( isdefined( var_6.current_attackers ) )
var_4 = var_4 - var_6.current_attackers.size * level.cycle_data.current_attacker_in_zone_score_modifier;
if ( isdefined( var_1[var_6.name] ) && var_1[var_6.name] > level.cycle_data.group_break_away_distance_sq )
var_4 = var_4 + min( level.cycle_data.max_break_away_zone_score_increase, var_1[var_6.name] / level.cycle_data.group_break_away_distance_sq );
}
var_4 = var_4 - get_number_of_recently_used_spawn_points_in_zone( var_3 ) * level.cycle_data.recently_used_spawn_zone_score_modifier;
var_3.zone_score = var_4;
}
var_9 = [];
foreach ( var_3 in var_0 )
var_9[var_9.size] = var_3;
return sort_array( var_9, ::sort_zone_score_func );
}
calculate_player_proximity_scores()
{
var_0 = [];
if ( level.players.size <= 2 )
return var_0;
for ( var_1 = 0; var_1 < level.players.size; var_1++ )
{
var_2 = level.players[var_1].name;
if ( !isdefined( var_0[var_2] ) )
var_0[var_2] = 100000000.0;
for ( var_3 = var_1 + 1; var_3 < level.players.size; var_3++ )
{
var_4 = distancesquared( level.players[var_1].origin, level.players[var_3].origin );
if ( var_4 < var_0[var_2] )
var_0[var_2] = var_4;
var_5 = level.players[var_3].name;
if ( !isdefined( var_0[var_5] ) || var_4 < var_0[var_5] )
var_0[var_5] = var_4;
}
}
return var_0;
}
get_number_of_recently_used_spawn_points_in_zone( var_0 )
{
var_1 = 0;
var_2 = gettime();
for ( var_3 = 0; var_3 < level.cycle_data.spawn_zones[var_0.name].spawn_nodes.size; var_3++ )
{
var_4 = level.cycle_data.spawn_zones[var_0.name].spawn_nodes[var_3]["location"];
if ( isdefined( var_4.last_used_time ) )
{
var_5 = var_2 - var_4.last_used_time;
if ( var_5 < level.cycle_data.spawn_point_last_used_duration )
var_1++;
}
}
return var_1;
}
sort_zone_score_func( var_0, var_1, var_2 )
{
return var_0.zone_score > var_1.zone_score;
}
is_safe_spawn_location( var_0, var_1, var_2 )
{
if ( var_1 == "elite" )
return 1;
foreach ( var_4 in var_2 )
{
if ( distancesquared( var_0.origin, var_4.origin ) > level.cycle_data.safe_spawn_distance_sq )
continue;
if ( has_line_of_sight( var_0.origin, var_4.origin ) )
return 0;
}
return 1;
}
has_line_of_sight( var_0, var_1 )
{
while ( max_traces_reached() )
wait 0.05;
level.spawn_node_traces_this_frame++;
return bullettracepassed( var_0, var_1, 0, undefined );
}
get_current_player_volumes()
{
if ( isdefined( level.dlc_get_current_player_volumes_override_func ) )
return level [[ level.dlc_get_current_player_volumes_override_func ]]();
var_0 = [];
var_1 = [];
foreach ( var_3 in level.cycle_data.spawn_zones )
var_0[var_0.size] = var_3.volume;
foreach ( var_6 in level.players )
{
if ( !isalive( var_6 ) || var_6.sessionstate == "spectator" )
continue;
var_7 = var_6 getistouchingentities( var_0 );
foreach ( var_9 in var_7 )
{
var_10 = 0;
if ( !isdefined( var_1[var_9.script_linkname] ) )
{
var_11 = var_9.script_linkname;
var_1[var_11] = spawnstruct();
var_1[var_11].players = [];
var_1[var_11].origin = var_9.origin;
var_1[var_11].name = var_11;
}
var_10 = var_1[var_9.script_linkname].players.size;
var_1[var_9.script_linkname].players[var_10] = var_6;
}
}
return var_1;
}
max_traces_reached()
{
var_0 = 5;
if ( gettime() > level.spawn_node_traces_frame_time )
{
level.spawn_node_traces_frame_time = gettime();
level.spawn_node_traces_this_frame = 0;
}
return level.spawn_node_traces_this_frame >= var_0;
}
load_cycle_scalars_from_table( var_0 )
{
var_0.cycle_scalars = [];
if ( maps\mp\alien\_utility::is_casual_mode() )
{
level.cycle_health_scalar = level.casual_health_scalar;
level.cycle_damage_scalar = level.casual_damage_scalar;
level.cycle_reward_scalar = level.casual_reward_scalar;
level.cycle_score_scalar = level.casual_score_scalar;
}
else if ( maps\mp\alien\_utility::is_hardcore_mode() )
{
level.cycle_health_scalar = level.hardcore_health_scalar;
level.cycle_damage_scalar = level.hardcore_damage_scalar;
level.cycle_reward_scalar = level.hardcore_reward_scalar;
level.cycle_score_scalar = level.hardcore_score_scalar;
}
else
{
level.cycle_health_scalar = 1.0;
level.cycle_damage_scalar = 1.0;
level.cycle_reward_scalar = 1.0;
level.cycle_score_scalar = 1.0;
}
for ( var_1 = 500; var_1 <= 599; var_1++ )
{
var_2 = tablelookup( level.alien_cycle_table, 0, var_1, 1 );
if ( var_2 == "" )
break;
var_2 = int( var_2 );
var_3 = spawnstruct();
var_3.health = float( tablelookup( level.alien_cycle_table, 0, var_1, 2 ) );
var_3.damage = float( tablelookup( level.alien_cycle_table, 0, var_1, 3 ) );
var_3.reward = float( tablelookup( level.alien_cycle_table, 0, var_1, 4 ) );
var_3.score = float( tablelookup( level.alien_cycle_table, 0, var_1, 5 ) );
add_cycle_scalar( int( var_2 ), var_3, var_0 );
}
}
add_cycle_scalar( var_0, var_1, var_2 )
{
var_2.cycle_scalars[var_0] = var_1;
}
set_cycle_scalars( var_0 )
{
if ( maps\mp\alien\_utility::is_hardcore_mode() )
{
level.cycle_health_scalar = level.cycle_data.cycle_scalars[var_0].health * level.hardcore_health_scalar;
level.cycle_damage_scalar = level.cycle_data.cycle_scalars[var_0].damage * level.hardcore_damage_scalar;
level.cycle_reward_scalar = level.cycle_data.cycle_scalars[var_0].reward * level.hardcore_reward_scalar;
level.cycle_score_scalar = level.cycle_data.cycle_scalars[var_0].score * level.hardcore_score_scalar;
}
else if ( maps\mp\alien\_utility::is_casual_mode() )
{
level.cycle_health_scalar = level.cycle_data.cycle_scalars[var_0].health * level.casual_health_scalar;
level.cycle_damage_scalar = level.cycle_data.cycle_scalars[var_0].damage * level.casual_damage_scalar;
level.cycle_reward_scalar = level.cycle_data.cycle_scalars[var_0].reward * level.casual_reward_scalar;
level.cycle_score_scalar = level.cycle_data.cycle_scalars[var_0].score * level.casual_score_scalar;
}
else
{
level.cycle_health_scalar = level.cycle_data.cycle_scalars[var_0].health;
level.cycle_damage_scalar = level.cycle_data.cycle_scalars[var_0].damage;
level.cycle_reward_scalar = level.cycle_data.cycle_scalars[var_0].reward;
level.cycle_score_scalar = level.cycle_data.cycle_scalars[var_0].score;
}
}
init_spawn_node_info( var_0 )
{
var_0.spawn_node_info = [];
init_spawn_node_info_from_table( var_0 );
}
init_spawn_node_info_from_table( var_0 )
{
if ( !isdefined( level.spawn_node_info_table ) )
level.spawn_node_info_table = "mp/alien/spawn_node_info.csv";
for ( var_1 = 1; var_1 <= 100; var_1++ )
{
var_2 = tablelookup( level.spawn_node_info_table, 0, var_1, 1 );
if ( var_2 == "" )
break;
var_3 = spawnstruct();
var_3.validtype = tablelookup( level.spawn_node_info_table, 0, var_1, 2 );
var_3.scriptablestatus = getscriptablestatus( var_1 );
var_4 = [];
var_4["goon"] = grabvignetteinfo( var_2, var_1, 4, 5, 6, 7, 8, 9, 10 );
var_4["brute"] = grabvignetteinfo( var_2, var_1, 11, 12, 13, 14, 15, 16, 17 );
var_4["spitter"] = grabvignetteinfo( var_2, var_1, 18, 19, 20, 21, 22, 23, 24 );
var_4["seeder"] = grabvignetteinfo( var_2, var_1, 18, 19, 20, 21, 22, 23, 24 );
var_4["elite"] = grabvignetteinfo( var_2, var_1, 25, 26, 27, 28, 29, 30, 31 );
var_4["minion"] = grabvignetteinfo( var_2, var_1, 32, 33, 34, 35, 36, 37, 38 );
var_3.vignetteinfo = var_4;
var_0.spawn_node_info[var_2] = var_3;
}
}
grabvignetteinfo( var_0, var_1, var_2, var_3, var_4, var_5, var_6, var_7, var_8 )
{
var_9 = ";";
var_10 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_2 ) );
var_11 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_3 ) );
var_12 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_4 ) );
var_13 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_5 ) );
var_6 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_6 ) );
var_7 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_7 ) );
var_8 = replaceemptystringwithnone( tablelookup( level.spawn_node_info_table, 0, var_1, var_8 ) );
return var_10 + var_9 + var_11 + var_9 + var_12 + var_9 + var_13 + var_9 + var_6 + var_9 + var_7 + var_9 + var_8 + var_9 + var_0;
}
getscriptablestatus( var_0 )
{
var_1 = tablelookup( level.spawn_node_info_table, 0, var_0, 3 );
if ( maps\mp\agents\alien\_alien_agents::is_empty_string( var_1 ) )
return "always_on";
else
return "one_off";
}
replaceemptystringwithnone( var_0 )
{
if ( maps\mp\agents\alien\_alien_agents::is_empty_string( var_0 ) )
return "NONE";
return var_0;
}
load_cycle_drill_layer_from_table( var_0 )
{
var_0.cycle_drill_layers = [];
var_0.cycle_delay_times = [];
for ( var_1 = 600; var_1 <= 699; var_1++ )
{
var_2 = tablelookup( level.alien_cycle_table, 0, var_1, 1 );
if ( var_2 == "" )
break;
var_3 = tablelookup( level.alien_cycle_table, 0, var_1, 2 );
var_3 = strtok( var_3, " " );
for ( var_4 = 0; var_4 < var_3.size; var_4++ )
var_3[var_4] = int( var_3[var_4] );
var_0.cycle_drill_layers[int( var_2 )] = var_3;
var_5 = tablelookup( level.alien_cycle_table, 0, var_1, 3 );
var_0.cycle_delay_times[int( var_2 )] = float( var_5 );
}
}
load_random_hives_from_table()
{
var_0 = [];
for ( var_1 = 900; var_1 <= 999; var_1++ )
{
var_2 = tablelookup( level.alien_cycle_table, 0, var_1, 1 );
if ( var_2 == "" )
break;
var_3 = tablelookup( level.alien_cycle_table, 0, var_1, 2 );
var_3 = strtok( var_3, " " );
var_0 = common_scripts\utility::array_combine( var_0, get_hives_to_remove( int( var_2 ), var_3 ) );
}
level.removed_hives = var_0;
}
get_hives_to_remove( var_0, var_1 )
{
var_2 = var_1.size - var_0;
if ( var_2 == 0 )
return [];
var_1 = common_scripts\utility::array_randomize( var_1 );
var_3 = [];
for ( var_4 = 0; var_4 < var_2; var_4++ )
var_3[var_3.size] = var_1[var_4];
return var_3;
}