// 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; }