diff --git a/zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc b/zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc index 739d1b2..785ba01 100644 --- a/zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc +++ b/zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc @@ -57,11 +57,6 @@ init() enable_dog_rounds() { level.dog_rounds_enabled = 1; - - if ( !isdefined( level.dog_round_track_override ) ) - level.dog_round_track_override = ::dog_round_tracker; - - level thread [[ level.dog_round_track_override ]](); } dog_spawner_init() @@ -91,105 +86,6 @@ dog_spawner_init() level.enemy_dog_spawns = sys::getentarray( "zombie_spawner_dog_init", "targetname" ); } -dog_round_spawning() -{ - level endon( "end_of_round" ); - level endon( "intermission" ); - level.dog_targets = sys::getplayers(); - - for ( i = 0; i < level.dog_targets.size; i++ ) - level.dog_targets[i].hunted_by = 0; - -/# - level endon( "kill_round" ); - - if ( getdvarint( #"zombie_cheat" ) == 2 || getdvarint( #"zombie_cheat" ) >= 4 ) - return; -#/ - - if ( level.intermission ) - return; - - level.dog_intermission = 1; - level thread dog_round_aftermath(); - players = sys::getplayers(); - array_thread( players, ::play_dog_round ); - wait 1; - playsoundatposition( game["zmbdialog"]["prefix"] + "_event_dogstart_0", ( 0, 0, 0 ) ); - wait 6; - - if ( level.dog_round_count < 3 ) - max = players.size * 6; - else - max = players.size * 8; - -/# - if ( getdvar( #"force_dogs" ) != "" ) - max = getdvarint( #"force_dogs" ); -#/ - level.zombie_total = max; - dog_health_increase(); - count = 0; - while ( true ) - { - while ( get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 ) - wait 0.1; - - for ( num_player_valid = get_number_of_valid_players(); get_current_zombie_count() >= num_player_valid * 2; num_player_valid = get_number_of_valid_players() ) - wait 2; - - players = sys::getplayers(); - favorite_enemy = get_favorite_enemy(); - - if ( isdefined( level.dog_spawn_func ) ) - { - spawn_loc = [[ level.dog_spawn_func ]]( level.dog_spawners, favorite_enemy ); - ai = spawn_zombie( level.dog_spawners[0] ); - - if ( isdefined( ai ) ) - { - ai.favoriteenemy = favorite_enemy; - spawn_loc thread dog_spawn_fx( ai, spawn_loc ); - level.zombie_total--; - count++; - } - } - else - { - spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy ); - ai = spawn_zombie( level.dog_spawners[0] ); - - if ( isdefined( ai ) ) - { - ai.favoriteenemy = favorite_enemy; - spawn_point thread dog_spawn_fx( ai, spawn_point ); - level.zombie_total--; - count++; - flag_set( "dog_clips" ); - } - } - - waiting_for_next_dog_spawn( count, max ); - } -} - -waiting_for_next_dog_spawn( count, max ) -{ - default_wait = 1.5; - - if ( level.dog_round_count == 1 ) - default_wait = 3; - else if ( level.dog_round_count == 2 ) - default_wait = 2.5; - else if ( level.dog_round_count == 3 ) - default_wait = 2; - else - default_wait = 1.5; - - default_wait = default_wait - count / max; - wait( default_wait ); -} - dog_round_aftermath() { level waittill( "last_dog_down" ); @@ -232,52 +128,6 @@ dog_spawn_fx( ai, ent ) ai notify( "visible" ); } -dog_spawn_sumpf_logic( dog_array, favorite_enemy ) -{ - assert( dog_array.size > 0, "Dog Spawner array is empty." ); - dog_array = array_randomize( dog_array ); - - for ( i = 0; i < dog_array.size; i++ ) - { - if ( isdefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_array[i] ) - continue; - - if ( sys::distancesquared( dog_array[i].origin, favorite_enemy.origin ) > 160000 && sys::distancesquared( dog_array[i].origin, favorite_enemy.origin ) < 640000 ) - { - if ( sys::distancesquared( ( 0, 0, dog_array[i].origin[2] ), ( 0, 0, favorite_enemy.origin[2] ) ) > 10000 ) - continue; - else - { - level.old_dog_spawn = dog_array[i]; - return dog_array[i]; - } - } - } - - return dog_array[0]; -} - -dog_spawn_factory_logic( dog_array, favorite_enemy ) -{ - dog_locs = array_randomize( level.zombie_dog_locations ); - - for ( i = 0; i < dog_locs.size; i++ ) - { - if ( isdefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_locs[i] ) - continue; - - dist_squared = sys::distancesquared( dog_locs[i].origin, favorite_enemy.origin ); - - if ( dist_squared > 160000 && dist_squared < 1000000 ) - { - level.old_dog_spawn = dog_locs[i]; - return dog_locs[i]; - } - } - - return dog_locs[0]; -} - get_favorite_enemy() { dog_targets = sys::getplayers(); @@ -319,44 +169,6 @@ dog_health_increase() level.dog_health = 1600; } -dog_round_tracker() -{ - level.dog_round_count = 1; - level.next_dog_round = level.round_number + randomintrange( 4, 7 ); - old_spawn_func = level.round_spawn_func; - old_wait_func = level.round_wait_func; - - while ( true ) - { - level waittill( "between_round_over" ); -/# - if ( getdvarint( #"force_dogs" ) > 0 ) - level.next_dog_round = level.round_number; -#/ - - if ( level.round_number == level.next_dog_round ) - { - level.music_round_override = 1; - old_spawn_func = level.round_spawn_func; - old_wait_func = level.round_wait_func; - dog_round_start(); - level.round_spawn_func = ::dog_round_spawning; - level.next_dog_round = level.round_number + randomintrange( 4, 6 ); -/# - sys::getplayers()[0] iprintln( "Next dog round: " + level.next_dog_round ); -#/ - } - else if ( flag( "dog_round" ) ) - { - dog_round_stop(); - level.round_spawn_func = old_spawn_func; - level.round_wait_func = old_wait_func; - level.music_round_override = 0; - level.dog_round_count = level.dog_round_count + 1; - } - } -} - dog_round_start() { flag_set( "dog_round" ); @@ -654,66 +466,6 @@ dog_clip_monitor() special_dog_spawn( spawners, num_to_spawn ) { - dogs = getaispeciesarray( "all", "zombie_dog" ); - - if ( isdefined( dogs ) && dogs.size >= 9 ) - return false; - - if ( !isdefined( num_to_spawn ) ) - num_to_spawn = 1; - - spawn_point = undefined; - count = 0; - - while ( count < num_to_spawn ) - { - players = sys::getplayers(); - favorite_enemy = get_favorite_enemy(); - - if ( isdefined( spawners ) ) - { - spawn_point = spawners[randomint( spawners.size )]; - ai = spawn_zombie( spawn_point ); - - if ( isdefined( ai ) ) - { - ai.favoriteenemy = favorite_enemy; - spawn_point thread dog_spawn_fx( ai ); - count++; - flag_set( "dog_clips" ); - } - } - else if ( isdefined( level.dog_spawn_func ) ) - { - spawn_loc = [[ level.dog_spawn_func ]]( level.dog_spawners, favorite_enemy ); - ai = spawn_zombie( level.dog_spawners[0] ); - - if ( isdefined( ai ) ) - { - ai.favoriteenemy = favorite_enemy; - spawn_loc thread dog_spawn_fx( ai, spawn_loc ); - count++; - flag_set( "dog_clips" ); - } - } - else - { - spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy ); - ai = spawn_zombie( level.dog_spawners[0] ); - - if ( isdefined( ai ) ) - { - ai.favoriteenemy = favorite_enemy; - spawn_point thread dog_spawn_fx( ai, spawn_point ); - count++; - flag_set( "dog_clips" ); - } - } - - waiting_for_next_dog_spawn( count, num_to_spawn ); - } - - return true; } dog_run_think() diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/_round_manager.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/_round_manager.gsc index 968d52c..f5f92b4 100644 --- a/zm_ai_pack/scripts/zm/zm_ai_pack/_round_manager.gsc +++ b/zm_ai_pack/scripts/zm/zm_ai_pack/_round_manager.gsc @@ -6,45 +6,235 @@ main() { - scripts\zm\zm_ai_pack\rounds\_dog_rounds::main(); - register_special_round( "zombie_dog", scripts\zm\zm_ai_pack\rounds\_dog_rounds::round_spawning, - scripts\zm\zm_ai_pack\rounds\_dog_rounds::round_wait, - scripts\zm\zm_ai_pack\rounds\_dog_rounds::round_max, - scripts\zm\zm_ai_pack\rounds\_dog_rounds::round_chance, - scripts\zm\zm_ai_pack\rounds\_dog_rounds::round_next ); + set_dvar_if_unset( "rm_min_rounds_before_special_round", 3 ); + set_dvar_if_unset( "rm_max_rounds_before_special_round", 7 ); + set_dvar_if_unset( "rm_special_round_chance", 33 ); + set_dvar_if_unset( "rm_allow_same_round_as_last_round", 1 ); + + set_dvar_if_unset( "rm_allowed_special_rounds", "normal zombie_dog mechz brutus leaper ghost avogadro mixed" ); + set_dvar_if_unset( "rm_allowed_special_round_variants", "default" ); + set_dvar_if_unset( "rm_forced_special_round", "" ); + set_dvar_if_unset( "rm_forced_special_variant", "" ); + + level.special_round = sys::spawnstruct(); + level.special_round.current_data = sys::spawnstruct(); + level.special_round.current_data.round_type = ""; + level.special_round.current_data.variant = ""; + level.special_round.current_data.round_number = 0; + level.special_round.last_data = sys::spawnstruct(); + level.special_round.last_data.round_type = ""; + level.special_round.last_data.variant = ""; + level.special_round.last_data.round_number = 0; + level.normal_round = sys::spawnstruct(); + level.normal_round.current_data = sys::spawnstruct(); + level.normal_round.current_data.round_type = ""; + level.normal_round.current_data.variant = ""; + + scripts\zm\zm_ai_pack\rounds\_zombie_dog::main(); + register_special_round( "zombie_dog", "default", + scripts\zm\zm_ai_pack\rounds\_zombie_dog::round_spawning, + scripts\zm\zm_ai_pack\rounds\_zombie_dog::round_wait, + scripts\zm\zm_ai_pack\rounds\_zombie_dog::round_max, + scripts\zm\zm_ai_pack\rounds\_zombie_dog::round_over, + scripts\zm\zm_ai_pack\rounds\_zombie_dog::round_chance, + scripts\zm\zm_ai_pack\rounds\_zombie_dog::round_next ); + + register_special_round( "normal", "default", + scripts\zm\zm_ai_pack\rounds\_zombie::round_spawning, + scripts\zm\zm_ai_pack\rounds\_zombie::round_wait, + scripts\zm\zm_ai_pack\rounds\_zombie::round_max, + scripts\zm\zm_ai_pack\rounds\_zombie::round_over, + scripts\zm\zm_ai_pack\rounds\_zombie::round_chance, + scripts\zm\zm_ai_pack\rounds\_zombie::round_next ); } -register_special_round( round_type, round_difficulty_type, round_spawning_func, round_wait_func, round_max_func, round_chance_func, next_instance_func ) +register_special_round( round_type, variant_type, round_spawning_func, round_wait_func, round_max_func, between_round_over_func, round_chance_func, next_instance_func ) { if ( !isDefined( level.round_manager_special_rounds ) ) { level.round_manager_special_rounds = []; } + if ( !isDefined( level.round_manager_special_rounds[ round_type ] ) ) + { + level.round_manager_special_rounds[ round_type ] = []; + } + s = sys::spawnstruct(); - s.difficulty = round_difficulty_type; s.spawning_func = round_spawning_func; s.wait_func = round_wait_func; s.max_func = round_max_func; + s.between_round_over_func = between_round_over_func; s.chance_func = round_chance_func; s.next_instance_func = next_instance_func; - level.round_manager_special_rounds[ round_type ] = s; + s.active = false; + level.round_manager_special_rounds[ round_type ][ variant_type ] = s; } -register_special_spawning_during_normal_rounds_func( spawning_type, round_difficulty_type, spawning_func, spawning_portion_of_zombie_total_func, spawning_chance_func, spawning_limit_per_round_func, spawning_cooldown_func ) +register_mixed_round_spawning_behavior( spawning_type, variant_type, spawning_func, spawning_portion_of_zombie_total_func, spawning_chance_func, spawning_limit_per_round_func, spawning_cooldown_func ) { if ( !isDefined( level.round_manager_normal_round_spawning_behaviors ) ) { level.round_manager_normal_round_spawning_behaviors = []; } + + if ( !isDefined( level.round_manager_normal_round_spawning_behaviors[ spawning_type ] ) ) + { + level.round_manager_normal_round_spawning_behaviors[ spawning_type ] = []; + } s = sys::spawnstruct(); - s.difficulty = round_difficulty_type; s.spawning_func = spawning_func; s.portion_of_zombie_total_func = spawning_portion_of_zombie_total_func; s.chance_func = spawning_chance_func; s.limit_per_round_func = spawning_limit_per_round_func; s.cooldown_func = spawning_cooldown_func; - level.round_manager_normal_round_spawning_behaviors[ spawning_type ] = s; + level.round_manager_normal_round_spawning_behaviors[ spawning_type ][ variant_type ] = s; +} + +should_do_special_round() +{ + if ( getDvar( "rm_forced_special_round" ) != "" && getdvar( "rm_forced_special_variant" ) ) + { + return true; + } + + special_round_string = getDvar( "rm_allowed_special_rounds" ); + + if ( special_round_string == "" || special_round_string == "normal" ) + { + return false; + } + + normal_exists = false; + special_round_types = strTok( special_round_string, " " ); + for ( i = 0; i < special_round_types.size; i++ ) + { + if ( special_round_types[ i ] == "normal" ) + { + normal_exists = true; + } + } + + if ( !normal_exists ) + { + return true; + } + + min_round = getDvarInt( "rm_min_rounds_before_special_round" ); + max_round = getDvarInt( "rm_max_rounds_before_special_round" ); + + chance = getDvarInt( "rm_special_round_chance" ); + + special_round_diff = level.round_number - level.special_round.last_round; + + if ( special_round_diff >= max_round ) + { + return true; + } + + if ( special_round_diff >= min_round ) + { + return randomInt( 100 ) <= chance; + } + + return false; +} + +determine_current_round_type() +{ + return_value = sys::spawnstruct(); + return_value.round_number = level.round_number; + + should_do_special_round = should_do_special_round(); + + if ( !should_do_special_round || !isDefined( level.round_manager_special_rounds ) || level.round_manager_special_rounds.size <= 0 ) + { + return_value.round_type = "normal"; + return_value.variant = "default"; + level.normal_round.current_data = return_value; + return level.normal_round.current_data; + } + + level.special_round.last_data = level.special_round.current_data; + + forced_special_round = getdvar( "rm_forced_special_round" ); + forced_variant = getdvar( "rm_forced_special_variant" ); + if ( forced_special_round != "" && forced_variant != "" ) + { + if ( !isDefined( level.round_manager_special_rounds[ forced_special_round ] ) || !isDefined( level.round_manager_special_rounds[ forced_special_round ][ forced_variant ] ) ) + { + print( "Round Manager ERROR: Can't set special round and variant to " + forced_special_round + " and " + forced_variant + " because it wasn't registered" ); + assert( false ); + } + else + { + return_value.round_type = forced_special_round; + return_value.variant = forced_variant; + level.special_round.current_data = return_value; + return level.special_round.current_data; + } + } + + allowed_round_string = getDvar( "rm_allowed_special_rounds" ); + + variant_string = getdvar( "rm_allowed_special_round_variants" ); + pick_default_variant = variant_string == "" || variant_string == "default"; + possible_round_types_keys = strTok( allowed_round_string, " " ); + if ( !pick_default_variant ) + { + possible_variants_keys = strTok( variant_string, " " ); + } + else + { + possible_variants_keys = []; + possible_variants_keys[ 0 ] = "default"; + } + + max_iterations = 50; + current_iterations = 0; + + allow_repeats = getDvarInt( "rm_allow_same_round_as_last_round" ) != 0; + for (;;) + { + possible_round_types = array_randomize( possible_round_types_keys ); + for ( i = 0; i < possible_round_types.size; i++ ) + { + assert( isDefined( level.round_manager_special_rounds[ possible_round_types[ i ] ] ) ); + possible_variants = array_randomize( possible_variants_keys ); + + if ( !allow_repeats && possible_round_types.size > 1 && possible_round_types[ i ] == level.special_round.last_data.round_type ) + { + continue; + } + + assert( possible_variants.size > 0 ); + + for ( j = 0; j < possible_variants.size; j++ ) + { + assert( isDefined( level.round_manager_special_rounds[ possible_round_types[ i ] ][ possible_variants[ j ] ] ) ); + + if ( possible_round_types.size <= 1 || [[ level.round_manager_special_rounds[ possible_round_types[ i ] ][ possible_variants[ j ] ].chance_func ]]() + && [[ level.round_manager_special_rounds[ possible_round_types[ i ] ][ possible_variants[ j ] ].next_instance_func ]]() <= level.round_number ) + { + return_value.round_type = possible_round_types[ i ]; + return_value.variant = possible_variants[ j ]; + level.special_round.current_data = return_value; + return level.special_round.current_data; + } + } + } + + current_iterations++; + + if ( current_iterations >= max_iterations ) + { + assertmsg( "Round Manager ERROR: Reached max iterations for picking round type" ); + return_value.round_type = possible_round_types[ 0 ]; + return_value.variant = "default"; + level.special_round.current_data = return_value; + return level.special_round.current_data; + } + } } get_zombie_dog_array() @@ -57,271 +247,6 @@ get_zombie_dog_count() return get_zombie_dog_array().size; } -round_wait_override() -{ - level endon( "restart_round" ); -/# - if ( getdvarint( #"zombie_rise_test" ) ) - level waittill( "forever" ); -#/ -/# - while ( getdvarint( #"zombie_cheat" ) == 2 || getdvarint( #"zombie_cheat" ) >= 4 ) - wait 1; -#/ - wait 1; - - if ( flag( "dog_round" ) ) - { - wait 7; - - while ( get_zombie_dog_count() > 0 || level.zombie_total > 0 || level.intermission ) - { - wait 0.5; - } - - increment_dog_round_stat( "finished" ); - } - else - { - while ( true ) - { - should_wait = 0; - - if ( isdefined( level.is_ghost_round_started ) && [[ level.is_ghost_round_started ]]() ) - should_wait = 1; - else - should_wait = get_current_zombie_count() > 0 || level.zombie_total > 0 || level.intermission; - - if ( !should_wait ) - return; - - if ( flag( "end_round_wait" ) ) - return; - - wait 1.0; - } - } -} - -round_spawning_override() -{ - level endon( "intermission" ); - level endon( "end_of_round" ); - level endon( "restart_round" ); -/# - level endon( "kill_round" ); -#/ - - if ( level.intermission ) - return; - -/# - if ( getdvarint( #"zombie_cheat" ) == 2 || getdvarint( #"zombie_cheat" ) >= 4 ) - return; -#/ - - if ( level.zombie_spawn_locations.size < 1 ) - { -/# - assertmsg( "No active spawners in the map. Check to see if the zone is active and if it's pointing to spawners." ); -#/ - return; - } - - ai_calculate_health( level.round_number ); - count = 0; - players = get_players(); - - for ( i = 0; i < players.size; i++ ) - players[i].zombification_time = 0; - - max = level.zombie_vars["zombie_max_ai"]; - multiplier = level.round_number / 5; - - if ( multiplier < 1 ) - multiplier = 1; - - if ( level.round_number >= 10 ) - multiplier = multiplier * ( level.round_number * 0.15 ); - - player_num = get_players().size; - - if ( player_num == 1 ) - max = max + int( 0.5 * level.zombie_vars["zombie_ai_per_player"] * multiplier ); - else - max = max + int( ( player_num - 1 ) * level.zombie_vars["zombie_ai_per_player"] * multiplier ); - - if ( !isdefined( level.max_zombie_func ) ) - level.max_zombie_func = ::default_max_zombie_func; - - if ( !( isdefined( level.kill_counter_hud ) && level.zombie_total > 0 ) ) - { - level.zombie_total = [[ level.max_zombie_func ]]( max ); - level notify( "zombie_total_set" ); - } - - if ( isdefined( level.zombie_total_set_func ) ) - level thread [[ level.zombie_total_set_func ]](); - - if ( level.round_number < 10 || level.speed_change_max > 0 ) - level thread zombie_speed_up(); - - mixed_spawns = 0; - old_spawn = undefined; - - while ( true ) - { - while ( get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 ) - wait 0.1; - - while ( get_current_actor_count() >= level.zombie_actor_limit ) - { - clear_all_corpses(); - wait 0.1; - } - - flag_wait( "spawn_zombies" ); - - while ( level.zombie_spawn_locations.size <= 0 ) - wait 0.1; - - run_custom_ai_spawn_checks(); - spawn_point = level.zombie_spawn_locations[randomint( level.zombie_spawn_locations.size )]; - - if ( !isdefined( old_spawn ) ) - old_spawn = spawn_point; - else if ( spawn_point == old_spawn ) - spawn_point = level.zombie_spawn_locations[randomint( level.zombie_spawn_locations.size )]; - - old_spawn = spawn_point; - - if ( isdefined( level.mixed_rounds_enabled ) && level.mixed_rounds_enabled == 1 ) - { - spawn_dog = 0; - - if ( level.round_number > 30 ) - { - if ( randomint( 100 ) < 3 ) - spawn_dog = 1; - } - else if ( level.round_number > 25 && mixed_spawns < 3 ) - { - if ( randomint( 100 ) < 2 ) - spawn_dog = 1; - } - else if ( level.round_number > 20 && mixed_spawns < 2 ) - { - if ( randomint( 100 ) < 2 ) - spawn_dog = 1; - } - else if ( level.round_number > 15 && mixed_spawns < 1 ) - { - if ( randomint( 100 ) < 1 ) - spawn_dog = 1; - } - - if ( spawn_dog ) - { - keys = getarraykeys( level.zones ); - - for ( i = 0; i < keys.size; i++ ) - { - if ( level.zones[keys[i]].is_occupied ) - { - akeys = getarraykeys( level.zones[keys[i]].adjacent_zones ); - - for ( k = 0; k < akeys.size; k++ ) - { - if ( level.zones[akeys[k]].is_active && !level.zones[akeys[k]].is_occupied && level.zones[akeys[k]].zombie_dog_locations.size > 0 ) - { - maps\mp\zombies\_zm_ai_dogs::special_dog_spawn( undefined, 1 ); - level.zombie_total--; - wait_network_frame(); - } - } - } - } - } - } - - if ( isdefined( level.zombie_spawners ) ) - { - if ( isdefined( level.use_multiple_spawns ) && level.use_multiple_spawns ) - { - if ( isdefined( spawn_point.script_int ) ) - { - if ( isdefined( level.zombie_spawn[spawn_point.script_int] ) && level.zombie_spawn[spawn_point.script_int].size ) - spawner = random( level.zombie_spawn[spawn_point.script_int] ); - else - { -/# - assertmsg( "Wanting to spawn from zombie group " + spawn_point.script_int + "but it doens't exist" ); -#/ - } - } - else if ( isdefined( level.zones[spawn_point.zone_name].script_int ) && level.zones[spawn_point.zone_name].script_int ) - spawner = random( level.zombie_spawn[level.zones[spawn_point.zone_name].script_int] ); - else if ( isdefined( level.spawner_int ) && ( isdefined( level.zombie_spawn[level.spawner_int].size ) && level.zombie_spawn[level.spawner_int].size ) ) - spawner = random( level.zombie_spawn[level.spawner_int] ); - else - spawner = random( level.zombie_spawners ); - } - else - spawner = random( level.zombie_spawners ); - - ai = spawn_zombie( spawner, spawner.targetname, spawn_point ); - } - - if ( isdefined( ai ) ) - { - level.zombie_total--; - ai thread round_spawn_failsafe(); - count++; - } - - wait( level.zombie_vars["zombie_spawn_delay"] ); - wait_network_frame(); - } -} - -round_tracker() -{ - level.dog_round_count = 1; - level.next_dog_round = level.round_number + randomintrange( 4, 7 ); - old_spawn_func = level.round_spawn_func; - old_wait_func = level.round_wait_func; - - while ( true ) - { - level waittill( "between_round_over" ); -/# - if ( getdvarint( #"force_dogs" ) > 0 ) - level.next_dog_round = level.round_number; -#/ - - if ( level.round_number == level.next_dog_round ) - { - level.music_round_override = 1; - old_spawn_func = level.round_spawn_func; - old_wait_func = level.round_wait_func; - dog_round_start(); - level.round_spawn_func = ::dog_round_spawning; - level.next_dog_round = level.round_number + randomintrange( 4, 6 ); -/# - sys::getplayers()[0] iprintln( "Next dog round: " + level.next_dog_round ); -#/ - } - else if ( flag( "dog_round" ) ) - { - dog_round_stop(); - level.round_spawn_func = old_spawn_func; - level.round_wait_func = old_wait_func; - level.music_round_override = 0; - level.dog_round_count = level.dog_round_count + 1; - } - } -} - round_think_override( restart ) { if ( !isdefined( restart ) ) @@ -378,7 +303,7 @@ round_think_override( restart ) } maps\mp\zombies\_zm_powerups::powerup_round_start(); - players = get_players(); + players = sys::getplayers(); array_thread( players, maps\mp\zombies\_zm_blockers::rebuild_barrier_reward_reset ); if ( !( isdefined( level.headshots_only ) && level.headshots_only ) && !restart ) @@ -393,7 +318,13 @@ round_think_override( restart ) while ( level.zombie_spawn_locations.size <= 0 ) wait 0.1; - level thread [[ level.round_spawn_func ]](); + current_round_data = determine_current_round_type(); + + round_manager_inst = level.round_manager_special_rounds[ current_round_data.round_type ][ current_round_data.variant ]; + level.round_manager_special_rounds[ current_round_data.round_type ][ current_round_data.variant ].active = true; + level [[ round_manager_inst.max_func ]](); + level thread [[ round_manager_inst.spawning_func ]](); + //level thread [[ level.round_spawn_func ]](); level notify( "start_of_round" ); recordzombieroundstart(); players = getplayers(); @@ -409,7 +340,8 @@ round_think_override( restart ) if ( isdefined( level.round_start_custom_func ) ) [[ level.round_start_custom_func ]](); - [[ level.round_wait_func ]](); + level [[ round_manager_inst.wait_func ]](); + //[[ level.round_wait_func ]](); level.first_round = 0; level notify( "end_of_round" ); level thread maps\mp\zombies\_zm_audio::change_zombie_music( "round_end" ); @@ -418,7 +350,7 @@ round_think_override( restart ) if ( isdefined( level.round_end_custom_logic ) ) [[ level.round_end_custom_logic ]](); - players = get_players(); + players = sys::getplayers(); if ( isdefined( level.no_end_game_check ) && level.no_end_game_check ) { @@ -428,7 +360,7 @@ round_think_override( restart ) else if ( 1 != players.size ) level thread spectators_respawn(); - players = get_players(); + players = sys::getplayers(); array_thread( players, maps\mp\zombies\_zm_pers_upgrades_system::round_end ); timer = level.zombie_vars["zombie_spawn_delay"]; @@ -449,7 +381,7 @@ round_think_override( restart ) setroundsplayed( level.round_number ); matchutctime = getutc(); - players = get_players(); + players = sys::getplayers(); foreach ( player in players ) { @@ -463,6 +395,8 @@ round_think_override( restart ) check_quickrevive_for_hotjoin(); level round_over(); level notify( "between_round_over" ); + level.round_manager_special_rounds[ current_round_data.round_type ][ current_round_data.variant ].active = false; + level [[ round_manager_inst.between_round_over_func ]](); restart = 0; } } \ No newline at end of file diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_dog_rounds.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_avogadro.gsc similarity index 100% rename from zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_dog_rounds.gsc rename to zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_avogadro.gsc diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_brutus.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_brutus.gsc new file mode 100644 index 0000000..e69de29 diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_ghost.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_ghost.gsc new file mode 100644 index 0000000..e69de29 diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_leaper.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_leaper.gsc new file mode 100644 index 0000000..e69de29 diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_mechz.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_mechz.gsc new file mode 100644 index 0000000..e69de29 diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_mixed.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_mixed.gsc new file mode 100644 index 0000000..edee1eb --- /dev/null +++ b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_mixed.gsc @@ -0,0 +1,63 @@ +special_dog_spawn( spawners, num_to_spawn ) +{ + dogs = getaispeciesarray( "all", "zombie_dog" ); + + if ( isdefined( dogs ) && dogs.size >= 9 ) + return false; + + if ( !isdefined( num_to_spawn ) ) + num_to_spawn = 1; + + spawn_point = undefined; + count = 0; + + while ( count < num_to_spawn ) + { + players = sys::getplayers(); + favorite_enemy = get_favorite_enemy(); + + if ( isdefined( spawners ) ) + { + spawn_point = spawners[randomint( spawners.size )]; + ai = spawn_zombie( spawn_point ); + + if ( isdefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_point thread dog_spawn_fx( ai ); + count++; + flag_set( "dog_clips" ); + } + } + else if ( isdefined( level.dog_spawn_func ) ) + { + spawn_loc = [[ level.dog_spawn_func ]]( level.dog_spawners, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[0] ); + + if ( isdefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_loc thread dog_spawn_fx( ai, spawn_loc ); + count++; + flag_set( "dog_clips" ); + } + } + else + { + spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[0] ); + + if ( isdefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_point thread dog_spawn_fx( ai, spawn_point ); + count++; + flag_set( "dog_clips" ); + } + } + + waiting_for_next_dog_spawn( count, num_to_spawn ); + } + + return true; +} \ No newline at end of file diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_normal.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_normal.gsc new file mode 100644 index 0000000..e4815a8 --- /dev/null +++ b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_normal.gsc @@ -0,0 +1,204 @@ +#include maps\mp\zombies\_zm_utility; +#include common_scripts\utility; +#include maps\mp\_utility; + +#include maps\mp\zombies\_zm; + +default_max_zombie_func( max_num ) +{ +/# + count = getdvarint( #"zombie_default_max" ); + + if ( count > -1 ) + return count; +#/ + max = max_num; + + if ( level.round_number < 2 ) + max = int( max_num * 0.25 ); + else if ( level.round_number < 3 ) + max = int( max_num * 0.3 ); + else if ( level.round_number < 4 ) + max = int( max_num * 0.5 ); + else if ( level.round_number < 5 ) + max = int( max_num * 0.7 ); + else if ( level.round_number < 6 ) + max = int( max_num * 0.9 ); + + return max; +} + +round_max() +{ + players = sys::getplayers(); + + for ( i = 0; i < players.size; i++ ) + players[i].zombification_time = 0; + + max = level.zombie_vars["zombie_max_ai"]; + multiplier = level.round_number / 5; + + if ( multiplier < 1 ) + multiplier = 1; + + if ( level.round_number >= 10 ) + multiplier = multiplier * ( level.round_number * 0.15 ); + + player_num = get_players().size; + + if ( player_num == 1 ) + max = max + int( 0.5 * level.zombie_vars["zombie_ai_per_player"] * multiplier ); + else + max = max + int( ( player_num - 1 ) * level.zombie_vars["zombie_ai_per_player"] * multiplier ); + + if ( !isdefined( level.max_zombie_func ) ) + level.max_zombie_func = ::default_max_zombie_func; + + level.zombie_total = [[ level.max_zombie_func ]]( max ); + level notify( "zombie_total_set" ); + + if ( isdefined( level.zombie_total_set_func ) ) + level thread [[ level.zombie_total_set_func ]](); +} + +round_chance() +{ + return false; +} + +round_next() +{ + return level.round_number + 1; +} + +round_wait() +{ + level endon( "restart_round" ); +/# + if ( getdvarint( #"zombie_rise_test" ) ) + level waittill( "forever" ); +#/ +/# + while ( getdvarint( #"zombie_cheat" ) == 2 || getdvarint( #"zombie_cheat" ) >= 4 ) + wait 1; +#/ + wait 1; + + while ( true ) + { + should_wait = 0; + + if ( isdefined( level.is_ghost_round_started ) && [[ level.is_ghost_round_started ]]() ) + should_wait = 1; + else + should_wait = get_current_zombie_count() > 0 || level.zombie_total > 0 || level.intermission; + + if ( !should_wait ) + return; + + if ( flag( "end_round_wait" ) ) + return; + + wait 1.0; + } +} + +round_spawning() +{ + level endon( "intermission" ); + level endon( "end_of_round" ); + level endon( "restart_round" ); +/# + level endon( "kill_round" ); +#/ + + if ( level.intermission ) + return; + +/# + if ( getdvarint( #"zombie_cheat" ) == 2 || getdvarint( #"zombie_cheat" ) >= 4 ) + return; +#/ + + if ( level.zombie_spawn_locations.size < 1 ) + { +/# + assertmsg( "No active spawners in the map. Check to see if the zone is active and if it's pointing to spawners." ); +#/ + return; + } + + ai_calculate_health( level.round_number ); + count = 0; + + if ( level.round_number < 10 || level.speed_change_max > 0 ) + level thread zombie_speed_up(); + + mixed_spawns = 0; + old_spawn = undefined; + + while ( true ) + { + while ( get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 ) + wait 0.1; + + while ( get_current_actor_count() >= level.zombie_actor_limit ) + { + clear_all_corpses(); + wait 0.1; + } + + flag_wait( "spawn_zombies" ); + + while ( level.zombie_spawn_locations.size <= 0 ) + wait 0.1; + + run_custom_ai_spawn_checks(); + spawn_point = level.zombie_spawn_locations[randomint( level.zombie_spawn_locations.size )]; + + if ( !isdefined( old_spawn ) ) + old_spawn = spawn_point; + else if ( spawn_point == old_spawn ) + spawn_point = level.zombie_spawn_locations[randomint( level.zombie_spawn_locations.size )]; + + old_spawn = spawn_point; + + if ( isdefined( level.zombie_spawners ) ) + { + if ( isdefined( level.use_multiple_spawns ) && level.use_multiple_spawns ) + { + if ( isdefined( spawn_point.script_int ) ) + { + if ( isdefined( level.zombie_spawn[spawn_point.script_int] ) && level.zombie_spawn[spawn_point.script_int].size ) + spawner = random( level.zombie_spawn[spawn_point.script_int] ); + else + { +/# + assertmsg( "Wanting to spawn from zombie group " + spawn_point.script_int + "but it doens't exist" ); +#/ + } + } + else if ( isdefined( level.zones[spawn_point.zone_name].script_int ) && level.zones[spawn_point.zone_name].script_int ) + spawner = random( level.zombie_spawn[level.zones[spawn_point.zone_name].script_int] ); + else if ( isdefined( level.spawner_int ) && ( isdefined( level.zombie_spawn[level.spawner_int].size ) && level.zombie_spawn[level.spawner_int].size ) ) + spawner = random( level.zombie_spawn[level.spawner_int] ); + else + spawner = random( level.zombie_spawners ); + } + else + spawner = random( level.zombie_spawners ); + + ai = spawn_zombie( spawner, spawner.targetname, spawn_point ); + } + + if ( isdefined( ai ) ) + { + level.zombie_total--; + ai thread round_spawn_failsafe(); + count++; + } + + wait( level.zombie_vars["zombie_spawn_delay"] ); + wait_network_frame(); + } +} \ No newline at end of file diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_zombie_dog.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_zombie_dog.gsc new file mode 100644 index 0000000..63eb074 --- /dev/null +++ b/zm_ai_pack/scripts/zm/zm_ai_pack/rounds/_zombie_dog.gsc @@ -0,0 +1,203 @@ +#include maps\mp\zombies\_zm_utility; +#include common_scripts\utility; +#include maps\mp\_utility; + +#include maps\mp\zombies\_zm_ai_dogs; + +#include scripts\zm\zm_ai_pack\_round_manager; + +main() +{ + set_dvar_if_unset( "rm_dog_round_chance", 40 ); +} + +round_spawning() +{ + level endon( "end_of_round" ); + level endon( "intermission" ); + level.dog_targets = sys::getplayers(); + + for ( i = 0; i < level.dog_targets.size; i++ ) + level.dog_targets[i].hunted_by = 0; + +/# + level endon( "kill_round" ); + + if ( getdvarint( #"zombie_cheat" ) == 2 || getdvarint( #"zombie_cheat" ) >= 4 ) + return; +#/ + + if ( level.intermission ) + return; + + level.music_round_override = 1; + maps\mp\zombies\_zm_ai_dogs::dog_round_start(); + + level.dog_intermission = 1; + level thread maps\mp\zombies\_zm_ai_dogs::dog_round_aftermath(); + players = sys::getplayers(); + array_thread( players, maps\mp\zombies\_zm_ai_dogs::play_dog_round ); + wait 1; + playsoundatposition( game["zmbdialog"]["prefix"] + "_event_dogstart_0", ( 0, 0, 0 ) ); + wait 6; + + dog_health_increase(); + count = 0; + while ( true ) + { + while ( get_current_zombie_count() >= level.zombie_ai_limit || level.zombie_total <= 0 ) + wait 0.1; + + for ( num_player_valid = get_number_of_valid_players(); get_zombie_dog_count() >= num_player_valid * 2; num_player_valid = get_number_of_valid_players() ) + wait 2; + + players = sys::getplayers(); + favorite_enemy = maps\mp\zombies\_zm_ai_dogs::get_favorite_enemy(); + + if ( isdefined( level.dog_spawn_func ) ) + { + spawn_loc = [[ level.dog_spawn_func ]]( level.dog_spawners, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[0] ); + + if ( isdefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_loc thread maps\mp\zombies\_zm_ai_dogs::dog_spawn_fx( ai, spawn_loc ); + level.zombie_total--; + count++; + } + } + else + { + spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy ); + ai = spawn_zombie( level.dog_spawners[0] ); + + if ( isdefined( ai ) ) + { + ai.favoriteenemy = favorite_enemy; + spawn_point thread maps\mp\zombies\_zm_ai_dogs::dog_spawn_fx( ai, spawn_point ); + level.zombie_total--; + count++; + flag_set( "dog_clips" ); + } + } + + waiting_for_next_dog_spawn( count, max ); + } +} + +round_wait() +{ + wait 7; + + while ( get_zombie_dog_count() > 0 || level.zombie_total > 0 || level.intermission ) + { + wait 0.5; + } + + increment_dog_round_stat( "finished" ); +} + +round_max() +{ + players = sys::getplayers(); + if ( level.dog_round_count < 3 ) + max = players.size * 6; + else + max = players.size * 8; + +/# + if ( getdvar( #"force_dogs" ) != "" ) + max = getdvarint( #"force_dogs" ); +#/ + level.zombie_total = max; +} + +round_chance() +{ + + chance = getDvarInt( "rm_dog_round_chance" ); + + return randomInt( 100 ) <= chance; +} + +round_next() +{ + return level.special_round.last_data.round_number + randomintrange( getDvarInt( "rm_min_rounds_before_special_round" ), getDvarInt( "rm_max_rounds_before_special_round" ) ); +} + +waiting_for_next_dog_spawn( count, max ) +{ + default_wait = 1.5; + + if ( level.dog_round_count == 1 ) + default_wait = 3; + else if ( level.dog_round_count == 2 ) + default_wait = 2.5; + else if ( level.dog_round_count == 3 ) + default_wait = 2; + else + default_wait = 1.5; + + default_wait = default_wait - count / max; + wait( default_wait ); +} + +round_over() +{ + if ( !isDefined( level.dog_round_count ) ) + { + level.dog_round_count = 1; + } + + maps\mp\zombies\_zm_ai_dogs::dog_round_stop(); + level.music_round_override = 0; + level.dog_round_count = level.dog_round_count + 1; + flag_clear( "dog_round" ); +} + +dog_spawn_sumpf_logic( dog_array, favorite_enemy ) +{ + assert( dog_array.size > 0, "Dog Spawner array is empty." ); + dog_array = array_randomize( dog_array ); + + for ( i = 0; i < dog_array.size; i++ ) + { + if ( isdefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_array[i] ) + continue; + + if ( sys::distancesquared( dog_array[i].origin, favorite_enemy.origin ) > 160000 && sys::distancesquared( dog_array[i].origin, favorite_enemy.origin ) < 640000 ) + { + if ( sys::distancesquared( ( 0, 0, dog_array[i].origin[2] ), ( 0, 0, favorite_enemy.origin[2] ) ) > 10000 ) + continue; + else + { + level.old_dog_spawn = dog_array[i]; + return dog_array[i]; + } + } + } + + return dog_array[0]; +} + +dog_spawn_factory_logic( dog_array, favorite_enemy ) +{ + dog_locs = array_randomize( level.zombie_dog_locations ); + + for ( i = 0; i < dog_locs.size; i++ ) + { + if ( isdefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_locs[i] ) + continue; + + dist_squared = sys::distancesquared( dog_locs[i].origin, favorite_enemy.origin ); + + if ( dist_squared > 160000 && dist_squared < 1000000 ) + { + level.old_dog_spawn = dog_locs[i]; + return dog_locs[i]; + } + } + + return dog_locs[0]; +} \ No newline at end of file diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack_mod_main.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack_mod_main.gsc index 9ca3fc7..828b240 100644 --- a/zm_ai_pack/scripts/zm/zm_ai_pack_mod_main.gsc +++ b/zm_ai_pack/scripts/zm/zm_ai_pack_mod_main.gsc @@ -50,7 +50,7 @@ main() level.ai_data[ "mechz" ].init = maps\mp\zombies\_zm_ai_mechz::init; level.ai_data[ "mechz" ].should_execute = level.script != "zm_tomb"; level.ai_data[ "zombie_dog" ] = sys::spawnstruct(); - //level.ai_data[ "zombie_dog" ].main = maps\mp\zombies\_zm_ai_dogs::init; + level.ai_data[ "zombie_dog" ].main = maps\mp\zombies\_zm_ai_dogs::init; level.ai_data[ "zombie_dog" ].init = maps\mp\zombies\_zm_ai_dogs::enable_dog_rounds; level.ai_data[ "zombie_dog" ].should_execute = !( level.gametype == "zstandard" && getGametypeSetting( "allowDogs" ) == 1 );