From 5827f5dc404ade00a71e02c331db11e5963df6c1 Mon Sep 17 00:00:00 2001 From: JezuzLizard Date: Mon, 26 Feb 2024 14:43:10 -0800 Subject: [PATCH] Fix dogs on Nuketown. --- zm_ai_pack/maps/mp/zm_nuked.d3dbsp | 190 ++++++++++++++ zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc | 36 ++- zm_ai_pack/maps/mp/zombies/_zm_zonemgr.gsc | 21 ++ .../scripts/zm/zm_ai_pack_mod_debug_main.gsc | 9 + zm_ai_pack/scripts/zm/zm_ai_pack_mod_main.gsc | 243 +++++++++++++++++- zm_ai_pack/sys.gsc | 2 +- zm_ai_pack/zone_source/mod.zone | 2 + 7 files changed, 495 insertions(+), 8 deletions(-) diff --git a/zm_ai_pack/maps/mp/zm_nuked.d3dbsp b/zm_ai_pack/maps/mp/zm_nuked.d3dbsp index c2c173f..0ba9a39 100644 --- a/zm_ai_pack/maps/mp/zm_nuked.d3dbsp +++ b/zm_ai_pack/maps/mp/zm_nuked.d3dbsp @@ -11546,6 +11546,196 @@ "origin" "100 0 -500" "script_noteworthy" "zombie_dog_spawner" } +{ +"targetname" "culdesac_green_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-384.934 845.987 -63.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_yellow_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "563.594 909.484 -103.973" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_yellow_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "317.887 503.854 -60.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_yellow_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "394.412 -39.0415 -47.396" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_yellow_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "230.973 -469.761 -60.8377" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_green_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-494.014 83.4232 -46.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_green_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-254.848 336.21 -50.2869" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "culdesac_yellow_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "698.789 -164.511 -57.1405" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_f1_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "836.251 598.238 -56.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_f1_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "679.25 274.623 -56.5105" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_f1_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "993.575 334.033 -54.2811" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_f2_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "925.133 295.415 79.125" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_f2_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "660.95 221.104 79.125" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "1022.71 899.392 -126.239" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "1568.58 816.986 -60.6684" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "1675.88 249.702 -45.769" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "1304.43 164.747 -54.9502" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse2_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "1903.94 303.476 -52.6843" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_f1_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-665.451 413.733 -55.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_f1_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-916.521 537.634 -55.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_f2_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-857.697 493.433 80.125" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_f2_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-582.218 410.76 80.125" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-1223.21 40.3534 -64.0952" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-1699.86 346.968 -62.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-1950.66 458.804 -53.4965" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-1583.33 968.953 -63.875" +"classname" "script_struct" +"angles" "0 0 0" +} +{ +"targetname" "openhouse1_backyard_zone_spawners" +"script_noteworthy" "zombie_dog_location" +"origin" "-1131.15 812.042 -56.6833" +"classname" "script_struct" +"angles" "0 0 0" +} + { "classname" "actor_zm_transit_avogadro" "model" "c_zom_electrician_fb" 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 f5b39a2..739d1b2 100644 --- a/zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc +++ b/zm_ai_pack/maps/mp/zombies/_zm_ai_dogs.gsc @@ -13,6 +13,14 @@ init() { + if ( !isDefined( level._zm_ai_dogs_init_called ) ) + { + level._zm_ai_dogs_init_called = true; + } + else + { + return; + } level.dogs_enabled = 1; level.dog_rounds_enabled = 0; level.dog_round_count = 1; @@ -85,6 +93,7 @@ dog_spawner_init() dog_round_spawning() { + level endon( "end_of_round" ); level endon( "intermission" ); level.dog_targets = sys::getplayers(); @@ -106,7 +115,7 @@ dog_round_spawning() players = sys::getplayers(); array_thread( players, ::play_dog_round ); wait 1; - playsoundatposition( "vox_zmba_event_dogstart_0", ( 0, 0, 0 ) ); + playsoundatposition( game["zmbdialog"]["prefix"] + "_event_dogstart_0", ( 0, 0, 0 ) ); wait 6; if ( level.dog_round_count < 3 ) @@ -121,9 +130,11 @@ dog_round_spawning() level.zombie_total = max; dog_health_increase(); count = 0; - - while ( count < max ) + 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; @@ -248,7 +259,7 @@ dog_spawn_sumpf_logic( dog_array, favorite_enemy ) dog_spawn_factory_logic( dog_array, favorite_enemy ) { - dog_locs = array_randomize( level.enemy_dog_locations ); + dog_locs = array_randomize( level.zombie_dog_locations ); for ( i = 0; i < dog_locs.size; i++ ) { @@ -483,11 +494,21 @@ dog_fx_trail() self.fx_dog_trail sys::linkto( self, "tag_origin" ); } +get_zombie_dog_array() +{ + return getaispeciesarray( level.zombie_team, "zombie_dog" ); +} + +get_zombie_dog_count() +{ + return get_zombie_dog_array().size; +} + dog_death() { self waittill( "death" ); - if ( get_current_zombie_count() == 0 && level.zombie_total == 0 ) + if ( get_zombie_dog_count() <= 0 && level.zombie_total <= 0 ) { level.last_dog_origin = self.origin; level notify( "last_dog_down" ); @@ -585,6 +606,11 @@ dog_clip_monitor() clips_on = 0; level.dog_clips = sys::getentarray( "dog_clips", "targetname" ); + if ( !isDefined( level.dog_clips ) || level.dog_clips.size <= 0 ) + { + return; + } + while ( true ) { for ( i = 0; i < level.dog_clips.size; i++ ) diff --git a/zm_ai_pack/maps/mp/zombies/_zm_zonemgr.gsc b/zm_ai_pack/maps/mp/zombies/_zm_zonemgr.gsc index 57550fa..20f3af0 100644 --- a/zm_ai_pack/maps/mp/zombies/_zm_zonemgr.gsc +++ b/zm_ai_pack/maps/mp/zombies/_zm_zonemgr.gsc @@ -197,6 +197,7 @@ zone_init( zone_name ) spots = getstructarray( zone.volumes[0].target, "targetname" ); zone.spawn_locations = []; zone.dog_locations = []; + zone.zombie_dog_locations = []; zone.screecher_locations = []; zone.avogadro_locations = []; zone.inert_locations = []; @@ -230,6 +231,12 @@ zone_init( zone_name ) continue; } + if ( token == "zombie_dog_location" ) + { + zone.zombie_dog_locations[zone.zombie_dog_locations.size] = spots[i]; + continue; + } + if ( token == "screecher_location" ) { zone.screecher_locations[zone.screecher_locations.size] = spots[i]; @@ -341,6 +348,7 @@ reinit_zone_spawners() spots = getstructarray( zone.volumes[0].target, "targetname" ); zone.spawn_locations = []; zone.dog_locations = []; + zone.zombie_dog_locations = []; zone.screecher_locations = []; zone.avogadro_locations = []; zone.quad_locations = []; @@ -369,6 +377,12 @@ reinit_zone_spawners() continue; } + if ( token == "zombie_dog_location" ) + { + zone.zombie_dog_locations[zone.zombie_dog_locations.size] = spots[j]; + continue; + } + if ( token == "screecher_location" ) { zone.screecher_locations[zone.screecher_locations.size] = spots[j]; @@ -943,6 +957,7 @@ create_spawner_list( zkeys ) level.zombie_spawn_locations = []; level.inert_locations = []; level.enemy_dog_locations = []; + level.zombie_dog_locations = []; level.zombie_screecher_locations = []; level.zombie_avogadro_locations = []; level.quad_locations = []; @@ -976,6 +991,12 @@ create_spawner_list( zkeys ) level.enemy_dog_locations[level.enemy_dog_locations.size] = zone.dog_locations[x]; } + for ( x = 0; x < zone.zombie_dog_locations.size; x++ ) + { + if ( zone.zombie_dog_locations[x].is_enabled ) + level.zombie_dog_locations[level.zombie_dog_locations.size] = zone.zombie_dog_locations[x]; + } + for ( x = 0; x < zone.screecher_locations.size; x++ ) { if ( zone.screecher_locations[x].is_enabled ) diff --git a/zm_ai_pack/scripts/zm/zm_ai_pack_mod_debug_main.gsc b/zm_ai_pack/scripts/zm/zm_ai_pack_mod_debug_main.gsc index da83d8b..7633994 100644 --- a/zm_ai_pack/scripts/zm/zm_ai_pack_mod_debug_main.gsc +++ b/zm_ai_pack/scripts/zm/zm_ai_pack_mod_debug_main.gsc @@ -237,6 +237,10 @@ draw_zombie_spawn_location_box( origin, color, vec = ( 20, 20, 40 ) ) draw_zome_spawn_location_info_text( origin, color, zone_name, location_type_name ) { + if ( !level.players[ 0 ] is_player_looking_at( origin, 0.9, false ) ) + { + return; + } print3d( origin + ( 0, 0, 49 ), "ZONE:" + zone_name ); print3d( origin + ( 0, 0, 37 ), "TYPE:" + location_type_name ); print3d( origin + ( 0, 0, 25 ), "ORIGIN:" + origin ); @@ -288,6 +292,11 @@ draw_zombie_spawn_locations() draw_specific_zombie_spawn_locations( zone.dog_locations, zkeys[ z ], ( 0.8, 0.8, 0 ), "dog" ); + if ( isDefined( zone.zombie_dog_locations ) ) + { + draw_specific_zombie_spawn_locations( zone.zombie_dog_locations, zkeys[ z ], ( 0.3, 0.8, 0.3 ), "zombie_dog" ); + } + draw_specific_zombie_spawn_locations( zone.screecher_locations, zkeys[ z ], ( 0, 0.8, 0.8 ), "screecher" ); draw_specific_zombie_spawn_locations( zone.avogadro_locations, zkeys[ z ], ( 0.3, 0.8, 0.8 ), "avogadro" ); 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 3ea4d8d..0668353 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 @@ -2,6 +2,7 @@ #include common_scripts\utility; #include maps\mp\_utility; #include maps\mp\zombies\_zm_spawner; +#include maps\mp\zombies\_zm; #include maps\mp\zombies\_zm_ai_avogadro; #include maps\mp\zombies\_zm_ai_screecher; @@ -19,7 +20,8 @@ main() replace_single_function( "maps/mp/zombies/_zm_weap_slowgun", "can_be_paralyzed", ::can_be_paralyzed_override ); replace_single_function( "maps/mp/zombies/_zm_ai_sloth", "watch_crash_trigger", ::watch_crash_trigger_override ); - + pluto_sys::replacefunc( maps\mp\zombies\_zm::round_spawning, ::round_spawning_override ); + pluto_sys::replacefunc( maps\mp\zombies\_zm::round_wait, ::round_wait_override ); level.script = toLower( getDvar( "mapname" ) ); level.gametype = toLower( getDvar( "g_gametype" ) ); @@ -47,7 +49,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 ); @@ -397,4 +399,241 @@ increment_enemy_count( who ) { level.zombie_total++; } +} + +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(); + } +} + +get_zombie_dog_array() +{ + return getaispeciesarray( level.zombie_team, "zombie_dog" ); +} + +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; + } + } } \ No newline at end of file diff --git a/zm_ai_pack/sys.gsc b/zm_ai_pack/sys.gsc index 92ec993..d5aff5e 100644 --- a/zm_ai_pack/sys.gsc +++ b/zm_ai_pack/sys.gsc @@ -43,7 +43,7 @@ @/ loadfx( fx_name ) { - loadfx( fx_name ); + return loadfx( fx_name ); } /@ diff --git a/zm_ai_pack/zone_source/mod.zone b/zm_ai_pack/zone_source/mod.zone index c751ff4..f1d9979 100644 --- a/zm_ai_pack/zone_source/mod.zone +++ b/zm_ai_pack/zone_source/mod.zone @@ -59,6 +59,8 @@ script,clientscripts/mp/zombies/_zm_ai_screecher.csc script,maps/mp/zombies/_zm_ai_leaper.gsc script,clientscripts/mp/zombies/_zm_ai_leaper.csc +script,maps/mp/zombies/_zm_zonemgr.gsc + script,scripts/zm/zm_ai_pack_mod_debug_main.csc script,scripts/zm/zm_ai_pack_mod_debug_main.gsc script,scripts/zm/zm_ai_pack_mod_main.csc