Jump to content

Kino CODE


Recommended Posts

  • Replies 41
  • Created
  • Last Reply

Top Posters In This Topic

He is talking about the programming code... I also think there are some easter eggs we have not found.

Kino Der Toten means Movies Of The Dead.

Well, We have found movies, Of the dead. The people in the movies are presumed to be dead.

And well they are movies. Thus meaning Movies of the dead.

This still does not help the fact we have only found 2 voice tapes on the map, why would they put 3 movies and only 2 voice tapes?

Link to comment

Thanks for clearing that up and yes i am talking about the programming code used to describe the game in an IF-THEN environment. I would love to take a look at the code for kino der toten because there is alot of mysterious things going on in this map!!

Link to comment

Thanks for clearing that up and yes i am talking about the programming code used to describe the game in an IF-THEN environment. I would love to take a look at the code for kino der toten because there is alot of mysterious things going on in this map!!

If i could get a editors edition of this map where i could strip it down id find the thrid radio darn it

Link to comment

Here's what I got... I'll even throw in some Bonus Stuff!!!

Zombie_theater

#include common_scripts\utility;
#include maps\_utility;
#include maps\_zombiemode_utility;
#include maps\_zombiemode_zone_manager;
//#include maps\_zombiemode_protips;

#include maps\zombie_theater_magic_box;
#include maps\zombie_theater_movie_screen;
#include maps\zombie_theater_quad;
#include maps\zombie_theater_teleporter;

main()
{

maps\zombie_theater_fx::main();
maps\zombie_theater_amb::main();

PreCacheModel("zombie_zapper_cagelight_red");
precachemodel("zombie_zapper_cagelight_green");
precacheShader("ac130_overlay_grain");
precacheshellshock( "electrocution" );
// ww: model used for ee rooms
PreCacheModel( "zombie_theater_reelcase_obj" );
PreCacheShader( "zom_icon_theater_reel" );
// ww: viewmodel arms for the level
PreCacheModel( "viewmodel_usa_pow_arms" ); // Dempsey
PreCacheModel( "viewmodel_rus_prisoner_arms" ); // Nikolai
PreCacheModel( "viewmodel_vtn_nva_standard_arms" );// Takeo
PreCacheModel( "viewmodel_usa_hazmat_arms" );// Richtofen
// DSM: models for light changing
PreCacheModel("zombie_zapper_cagelight_on");
precachemodel("zombie_zapper_cagelight");
PreCacheModel("lights_hang_single");
precachemodel("lights_hang_single_on_nonflkr");
precachemodel("zombie_theater_chandelier1arm_off");
precachemodel("zombie_theater_chandelier1arm_on");
precachemodel("zombie_theater_chandelier1_off");
precachemodel("zombie_theater_chandelier1_on");




if(GetDvarInt( #"artist") > 0)
{
return;
}

level.dogs_enabled = true;
level.random_pandora_box_start = true;

level.zombie_anim_override = maps\zombie_theater::anim_override_func;

// Animations needed for door initialization
curtain_anim_init();

level thread maps\_callbacksetup::SetupCallbacks();

level.quad_move_speed = 35;
level.quad_traverse_death_fx = maps\zombie_theater_quad::quad_traverse_death_fx;
level.quad_explode = true;

level.dog_spawn_func = maps\_zombiemode_ai_dogs::dog_spawn_factory_logic;
level.exit_level_func = ::theater_exit_level;

// Special zombie types, engineer and quads.
level.custom_ai_type = [];
level.custom_ai_type = array_add( level.custom_ai_type, maps\_zombiemode_ai_quad::init );
level.custom_ai_type = array_add( level.custom_ai_type, maps\_zombiemode_ai_dogs::init );

level.door_dialog_function = maps\_zombiemode::play_door_dialog;
level.first_round_spawn_func = true;
//level.round_spawn_func = maps\zombie_theater_quad::Intro_Quad_Spawn;;

include_weapons();
include_powerups();

level.use_zombie_heroes = true;
level.disable_protips = 1;

// DO ACTUAL ZOMBIEMODE INIT
maps\_zombiemode::main();
// maps\_zombiemode_timer::init();

// Turn off generic battlechatter - Steve G
battlechatter_off("allies");
battlechatter_off("axis");

maps\_zombiemode_ai_dogs::enable_dog_rounds();

init_zombie_theater();

// Setup the levels Zombie Zone Volumes
maps\_compass::setupMiniMap("menu_map_zombie_theater");
level.ignore_spawner_func = ::theater_ignore_spawner;

level.zone_manager_init_func = ::theater_zone_init;
init_zones[0] = "foyer_zone";
init_zones[1] = "foyer2_zone";
level thread maps\_zombiemode_zone_manager::manage_zones( init_zones );

level thread maps\_zombiemode_auto_turret::init();
level thread set_rope_collision();

// DCS: extracam screen stuff.
level.extracam_screen = GetEnt("theater_extracam_screen", "targetname");
level.extracam_screen Hide();
clientnotify("camera_stop");

init_sounds();
level thread add_powerups_after_round_1();

visionsetnaked( "zombie_theater", 0 );
// DSM: Setting chandelier Scale
chandelier = getentarray("theater_chandelier","targetname");
array_thread( chandelier, ::theater_chandelier_model_scale );

maps\zombie_theater_teleporter::teleport_pad_hide_use();



}


#using_animtree( "generic_human" );
anim_override_func()
{
level.scr_anim["zombie"]["walk7"] = %ai_zombie_walk_v8; //goose step walk
}




//*****************************************************************************


#using_animtree( "zombie_theater" );
curtain_anim_init()
{
level.scr_anim["curtains_move"] = %o_zombie_theatre_curtain;
}

theater_playanim( animname )
{
self UseAnimTree(#animtree);
self animscripted(animname + "_done", self.origin, self.angles, level.scr_anim[animname],"normal", undefined, 2.0 );
}


//*****************************************************************************
// WEAPON FUNCTIONS
//
// Include the weapons that are only in your level so that the cost/hints are accurate
// Also adds these weapons to the random treasure chest.
// Copy all include_weapon lines over to the level.csc file too - removing the weighting funcs...
//*****************************************************************************
include_weapons()
{
include_weapon( "frag_grenade_zm", false, true );
include_weapon( "claymore_zm", false, true );

// Weapons - Pistols
include_weapon( "m1911_zm", false ); // colt
include_weapon( "m1911_upgraded_zm", false );
include_weapon( "python_zm" ); // 357
include_weapon( "python_upgraded_zm", false );
include_weapon( "cz75_zm" );
include_weapon( "cz75_upgraded_zm", false );

// Weapons - Semi-Auto Rifles
include_weapon( "m14_zm", false, true ); // gewehr43
include_weapon( "m14_upgraded_zm", false );

// Weapons - Burst Rifles
include_weapon( "m16_zm", false, true );
include_weapon( "m16_gl_upgraded_zm", false );
include_weapon( "g11_lps_zm" );
include_weapon( "g11_lps_upgraded_zm", false );
include_weapon( "famas_zm" );
include_weapon( "famas_upgraded_zm", false );

// Weapons - SMGs
include_weapon( "ak74u_zm", false, true ); // thompson, mp40, bar
include_weapon( "ak74u_upgraded_zm", false );
include_weapon( "mp5k_zm", false, true );
include_weapon( "mp5k_upgraded_zm", false );
include_weapon( "mp40_zm", false, true );
include_weapon( "mp40_upgraded_zm", false );
include_weapon( "mpl_zm", false, true );
include_weapon( "mpl_upgraded_zm", false );
include_weapon( "pm63_zm", false, true );
include_weapon( "pm63_upgraded_zm", false );
include_weapon( "spectre_zm" );
include_weapon( "spectre_upgraded_zm", false );

// Weapons - Dual Wield
include_weapon( "cz75dw_zm" );
include_weapon( "cz75dw_upgraded_zm", false );

// Weapons - Shotguns
include_weapon( "ithaca_zm", false, true ); // shotgun
include_weapon( "ithaca_upgraded_zm", false );
include_weapon( "rottweil72_zm", false, true );
include_weapon( "rottweil72_upgraded_zm", false );
include_weapon( "spas_zm" ); //
include_weapon( "spas_upgraded_zm", false );
include_weapon( "hs10_zm" );
include_weapon( "hs10_upgraded_zm", false );

// Weapons - Assault Rifles
include_weapon( "aug_acog_zm" );
include_weapon( "aug_acog_mk_upgraded_zm", false );
include_weapon( "galil_zm" );
include_weapon( "galil_upgraded_zm", false );
include_weapon( "commando_zm" );
include_weapon( "commando_upgraded_zm", false );
include_weapon( "fnfal_zm" );
include_weapon( "fnfal_upgraded_zm", false );

// Weapons - Sniper Rifles
include_weapon( "dragunov_zm" ); // ptrs41
include_weapon( "dragunov_upgraded_zm", false );
include_weapon( "l96a1_zm" );
include_weapon( "l96a1_upgraded_zm", false );

// Weapons - Machineguns
include_weapon( "rpk_zm" ); // mg42, 30 cal, ppsh
include_weapon( "rpk_upgraded_zm", false );
include_weapon( "hk21_zm" );
include_weapon( "hk21_upgraded_zm", false );

// Weapons - Misc
include_weapon( "m72_law_zm" );
include_weapon( "m72_law_upgraded_zm", false );
include_weapon( "china_lake_zm" );
include_weapon( "china_lake_upgraded_zm", false );

// Weapons - Special
include_weapon( "zombie_cymbal_monkey" );
include_weapon( "ray_gun_zm" );
include_weapon( "ray_gun_upgraded_zm", false );

include_weapon( "thundergun_zm", true );
include_weapon( "thundergun_upgraded_zm", false );
include_weapon( "crossbow_explosive_zm" );
include_weapon( "crossbow_explosive_upgraded_zm", false );

include_weapon( "knife_ballistic_zm", true );
include_weapon( "knife_ballistic_upgraded_zm", false );
include_weapon( "knife_ballistic_bowie_zm", false );
include_weapon( "knife_ballistic_bowie_upgraded_zm", false );
level._uses_retrievable_ballisitic_knives = true;

// limited weapons
maps\_zombiemode_weapons::add_limited_weapon( "m1911_zm", 0 );
maps\_zombiemode_weapons::add_limited_weapon( "thundergun_zm", 1 );
maps\_zombiemode_weapons::add_limited_weapon( "crossbow_explosive_zm", 1 );
maps\_zombiemode_weapons::add_limited_weapon( "knife_ballistic_zm", 1 );

precacheItem( "explosive_bolt_zm" );
precacheItem( "explosive_bolt_upgraded_zm" );


// get the bowie into the collector achievement list
level.collector_achievement_weapons = array_add( level.collector_achievement_weapons, "bowie_knife_zm" );
}

//*****************************************************************************
// POWERUP FUNCTIONS
//*****************************************************************************

include_powerups()
{
include_powerup( "nuke" );
include_powerup( "insta_kill" );
include_powerup( "double_points" );
include_powerup( "full_ammo" );
include_powerup( "carpenter" );
include_powerup( "fire_sale" );
}

add_powerups_after_round_1()
{

//want to precache all the stuff for these powerups, but we don't want them to be available in the first round
level.zombie_powerup_array = array_remove (level.zombie_powerup_array, "nuke");
level.zombie_powerup_array = array_remove (level.zombie_powerup_array, "fire_sale");

while (1)
{
if (level.round_number > 1)
{
level.zombie_powerup_array = array_add(level.zombie_powerup_array, "nuke");
level.zombie_powerup_array = array_add(level.zombie_powerup_array, "fire_sale");
break;
}
wait (1);
}
}

//*****************************************************************************

init_zombie_theater()
{
flag_init( "curtains_done" );
flag_init( "lobby_occupied" );
flag_init( "dining_occupied" );
flag_init( "special_quad_round" );


level thread electric_switch();

// Setup the magic box map
thread maps\zombie_theater_magic_box::magic_box_init();

//setup the movie screen
level thread maps\zombie_theater_movie_screen::initMovieScreen();

// setup breakaway roofs
thread maps\zombie_theater_quad::init_roofs();

level thread teleporter_intro();
}

//*****************************************************************************
teleporter_intro()
{
flag_wait( "all_players_spawned" );

wait( 0.25 );

players = get_players();
for ( i = 0; i {
players[i] SetTransported( 2 );
}

playsoundatposition( "evt_beam_fx_2d", (0,0,0) );
playsoundatposition( "evt_pad_cooldown_2d", (0,0,0) );
}

//*****************************************************************************
// ELECTRIC SWITCH
// once this is used, it activates other objects in the map
// and makes them available to use
//*****************************************************************************
electric_switch()
{
trig = getent("use_elec_switch","targetname");
trig sethintstring(&"ZOMBIE_ELECTRIC_SWITCH");
trig setcursorhint( "HINT_NOICON" );


level thread wait_for_power();

trig waittill("trigger",user);

trig delete();
flag_set( "power_on" );
Objective_State(8,"done");
}


//
// Wait for the power_on flag to be set. This is needed to work in conjunction with
// the devgui cheat.
//
wait_for_power()
{
master_switch = getent("elec_switch","targetname");
master_switch notsolid();

flag_wait( "power_on" );

master_switch rotateroll(-90,.3);
master_switch playsound("zmb_switch_flip");

clientnotify( "ZPO" ); // Zombie power on.

master_switch waittill("rotatedone");
playfx(level._effect["switch_sparks"] ,getstruct("elec_switch_fx","targetname").origin);

//Sound - Shawn J - adding temp sound to looping sparks & turning on power sources
master_switch playsound("zmb_turn_on");

//get the teleporter ready
maps\zombie_theater_teleporter::teleporter_init();
wait_network_frame();
// Set Perk Machine Notifys
level notify("revive_on");
wait_network_frame();
level notify("juggernog_on");
wait_network_frame();
level notify("sleight_on");
wait_network_frame();
level notify("doubletap_on");
wait_network_frame();
level notify("Pack_A_Punch_on" );
wait_network_frame();

// start quad round
// Set number of quads per round
players = get_players();
level.quads_per_round = 4 * players.size; // initial setting

level notify("quad_round_can_end");
level.delay_spawners = undefined;

//maps\zombie_theater_quad::begin_quad_introduction("theater_round");
//level.round_spawn_func = maps\zombie_theater_quad::Intro_Quad_Spawn;;
//maps\zombie_theater_quad::Theater_Quad_Round();

// DCS: start check for potential quad waves after power turns on.
level thread quad_wave_init();
}

//AUDIO

init_sounds()
{
maps\_zombiemode_utility::add_sound( "wooden_door", "zmb_door_wood_open" );
maps\_zombiemode_utility::add_sound( "fence_door", "zmb_door_fence_open" );
}


// *****************************************************************************
// Zone management
// *****************************************************************************

theater_zone_init()
{
flag_init( "always_on" );
flag_set( "always_on" );

// foyer_zone
add_adjacent_zone( "foyer_zone", "foyer2_zone", "always_on" );

add_adjacent_zone( "foyer_zone", "vip_zone", "magic_box_foyer1" );
add_adjacent_zone( "foyer2_zone", "crematorium_zone", "magic_box_crematorium1" );
add_adjacent_zone( "foyer_zone", "crematorium_zone", "magic_box_crematorium1" );

// vip_zone
add_adjacent_zone( "vip_zone", "dining_zone", "vip_to_dining" );

// crematorium_zone
add_adjacent_zone( "crematorium_zone", "alleyway_zone", "magic_box_alleyway1" );

// dining_zone
add_adjacent_zone( "dining_zone", "dressing_zone", "dining_to_dressing" );

// dressing_zone
add_adjacent_zone( "dressing_zone", "stage_zone", "magic_box_dressing1" );

// stage_zone
add_adjacent_zone( "stage_zone", "west_balcony_zone", "magic_box_west_balcony2" );

// theater_zone
add_adjacent_zone( "theater_zone", "foyer2_zone", "power_on" );
add_adjacent_zone( "theater_zone", "stage_zone", "power_on" );

// west_balcony_zone
add_adjacent_zone( "west_balcony_zone", "alleyway_zone", "magic_box_west_balcony1" );
}

theater_ignore_spawner( spawner )
{
// no curtains, no quads
if ( !flag( "curtains_done" ) )
{
if ( spawner.script_noteworthy == "quad_zombie_spawner" )
{
return true;
}
}

// DCS: when special round happens, first half quads.
if ( flag( "special_quad_round" ) )
{
if ( spawner.script_noteworthy != "quad_zombie_spawner" )
{
return true;
}
}

if ( !flag( "lobby_occupied" ) )
{
if ( spawner.script_noteworthy == "quad_zombie_spawner" && spawner.targetname == "foyer_zone_spawners" )
{
return true;
}
}

if ( !flag( "dining_occupied" ) )
{
if ( spawner.script_noteworthy == "quad_zombie_spawner" && spawner.targetname == "zombie_spawner_dining" )
{
return true;
}
}

return false;
}

// *****************************************************************************
// DCS: random round change quad emphasis
// This should only happen in zones where quads spawn into
// and crawl down the wall.
// potential zones: foyer_zone, theater_zone, stage_zone, dining_zone
// *****************************************************************************
quad_wave_init()
{
level thread time_for_quad_wave("foyer_zone");
level thread time_for_quad_wave("theater_zone");
level thread time_for_quad_wave("stage_zone");
level thread time_for_quad_wave("dining_zone");

level waittill( "end_of_round" );
flag_clear( "special_quad_round" );
}

time_for_quad_wave(zone_name)
{

if(!IsDefined(zone_name))
{
return;
}
zone = level.zones[ zone_name ];

// wait for round change.
level waittill( "between_round_over" );

//avoid dog rounds.
if ( IsDefined( level.next_dog_round ) && level.next_dog_round == level.round_number )
{
level thread time_for_quad_wave(zone_name);
return;
}

// ripped from spawn script for accuracy. -------------------------------------
max = level.zombie_vars["zombie_max_ai"];
multiplier = level.round_number / 5;
if( multiplier {
multiplier = 1;
}

if( level.round_number >= 10 )
{
multiplier *= level.round_number * 0.15;
}

player_num = get_players().size;

if( player_num == 1 )
{
max += int( ( 0.5 * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
}
else
{
max += int( ( ( player_num - 1 ) * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
}
// ripped from spawn script for accuracy. -------------------------------------

//percent chance.
chance = 100;
max_zombies = [[ level.max_zombie_func ]]( max );
current_round = level.round_number;

// every third round a chance of a quad wave.
if((level.round_number % 3 == 0) && chance >= RandomInt(100))
{
if(zone.is_occupied)
{
flag_set( "special_quad_round" );
maps\_zombiemode_zone_manager::reinit_zone_spawners();

while( level.zombie_total {
wait(0.1);
}

//level waittill( "end_of_round" );

flag_clear( "special_quad_round" );
maps\_zombiemode_zone_manager::reinit_zone_spawners();

}
}
level thread time_for_quad_wave(zone_name);
}
// DSM: Setting Chandelier Model Scale

theater_chandelier_model_scale()
{
flag_wait( "power_on" );

if( self.model == "zombie_theater_chandelier1arm_off")
{
self SetModel("zombie_theater_chandelier1arm_on");
}
else if( self.model == "zombie_theater_chandelier1_off")
{
self SetModel("zombie_theater_chandelier1_on");
}

}

set_rope_collision()
{
techrope = getentarray("techrope01", "targetname");
if(isdefined(techrope))
{

for( i = 0; i {
ropesetflag( techrope[i], "collide", 1 );
ropesetflag( techrope[i], "no_lod", 1 );
}
}
}

theater_exit_level()
{
zombies = GetAiArray( "axis" );
for ( i = 0; i {
zombies[i] thread theater_find_exit_point();
}
}

theater_find_exit_point()
{
self endon( "death" );

player = getplayers()[0];

dist_zombie = 0;
dist_player = 0;
dest = 0;

away = VectorNormalize( self.origin - player.origin );
endPos = self.origin + vector_scale( away, 600 );

locs = array_randomize( level.enemy_dog_locations );

for ( i = 0; i {
dist_zombie = DistanceSquared( locs[i].origin, endPos );
dist_player = DistanceSquared( locs[i].origin, player.origin );

if ( dist_zombie {
dest = i;
break;
}
}

self notify( "stop_find_flesh" );
self notify( "zombie_acquire_enemy" );

self setgoalpos( locs[dest].origin );

while ( 1 )
{
if ( !flag( "wait_and_revive" ) )
{
break;
}
wait_network_frame();
}

self thread maps\_zombiemode_spawner::find_flesh();
}
Zombie_Theater_AMB
//
// file: zombie_pentagon_amb.gsc
// description: level ambience script for zombie_pentagon
// scripter:
//
#include common_scripts\utility;
#include maps\_utility;
#include maps\_ambientpackage;
#include maps\_music;
#include maps\_zombiemode_utility;
#include maps\_busing;


main()
{
level thread setup_power_on_sfx();
level thread play_projecter_loop();
level thread play_projecter_soundtrack();
level thread setup_meteor_audio();
level thread setup_radio_egg_audio();
array_thread( GetEntArray( "portrait_egg", "targetname" ), ::portrait_egg_vox );
array_thread( GetEntArray( "location_egg", "targetname" ), ::location_egg_vox );
}

setup_power_on_sfx()
{
wait(5);
sound_emitters = getstructarray ("amb_power", "targetname");
flag_wait("power_on");
level thread play_evil_generator_audio();


for(i=0;i {
sound_emitters[i] thread play_emitter();

}
}

play_emitter()
{
wait (randomfloatrange (0.1, 1));
playsoundatposition ("amb_circuit", self.origin);
wait (randomfloatrange (0.05, 0.5));
soundloop = spawn ("script_origin", self.origin);
soundloop playloopsound (self.script_sound);
}

play_evil_generator_audio()
{
playsoundatposition ("evt_flip_sparks_left", (-544, 1320, 32));
playsoundatposition ("evt_flip_sparks_right", (-400, 1320, 32));

wait(2);

playsoundatposition ("evt_crazy_power_left", (-304, 1120, 344));
playsoundatposition ("evt_crazy_power_right", (408, 1136, 344));
wait(13);

playsoundatposition ("evt_crazy_power_left_end", (-304, 1120, 344));
playsoundatposition ("evt_crazy_power_right_end", (408, 1136, 344));
playsoundatposition ("evt_flip_switch_laugh_left", (-536, 1336, 704));
playsoundatposition ("evt_flip_switch_laugh_right", (576, 1336, 704));

level notify ("generator_done");
}

play_projecter_soundtrack()
{
level waittill( "generator_done");
wait(20);
//TEMP
speaker = spawn ("script_origin", (32, 1216, 592));
speaker playloopsound ("amb_projecter_soundtrack");
}

play_projecter_loop()
{
level waittill( "generator_done");
projecter = spawn ("script_origin", (-72, -144, 384));
projecter playloopsound ("amb_projecter");
}

setup_meteor_audio()
{
wait(1);
level.meteor_counter = 0;
level.music_override = false;
array_thread( GetEntArray( "meteor_egg_trigger", "targetname" ), ::meteor_egg );
}

play_music_easter_egg( player )
{
level.music_override = true;
level thread maps\_zombiemode_audio::change_zombie_music( "egg" );

wait(4);

if( IsDefined( player ) )
{
player maps\_zombiemode_audio::create_and_play_dialog( "eggs", "music_activate" );
}

wait(236);
level.music_override = false;
level thread maps\_zombiemode_audio::change_zombie_music( "wave_loop" );
}

meteor_egg()
{
if( !isdefined( self ) )
{
return;
}

self UseTriggerRequireLookAt();
self SetCursorHint( "HINT_NOICON" );
self PlayLoopSound( "zmb_meteor_loop" );

self waittill( "trigger", player );

self StopLoopSound( 1 );
player PlaySound( "zmb_meteor_activate" );

player maps\_zombiemode_audio::create_and_play_dialog( "eggs", "meteors", undefined, level.meteor_counter );

level.meteor_counter = level.meteor_counter + 1;

if( level.meteor_counter == 3 )
{
level thread play_music_easter_egg( player );
}
}

portrait_egg_vox()
{
if( !isdefined( self ) )
{
return;
}

self UseTriggerRequireLookAt();
self SetCursorHint( "HINT_NOICON" );

self waittill( "trigger", player );

type = "portrait_" + self.script_noteworthy;

player maps\_zombiemode_audio::create_and_play_dialog( "eggs", type );
}

location_egg_vox()
{
self waittill( "trigger", player );

if( RandomIntRange(0,101) >= 90 )
{
type = "room_" + self.script_noteworthy;
player maps\_zombiemode_audio::create_and_play_dialog( "eggs", type );
}
}

play_radio_egg( delay )
{
if( IsDefined( delay ) )
{
wait( delay );
}

if( !IsDefined( self ) )
return;

self PlaySound( "vox_zmb_egg_0" + level.radio_egg_counter );
level.radio_egg_counter++;
}

setup_radio_egg_audio()
{
wait(1);
level.radio_egg_counter = 0;
array_thread( GetEntArray( "audio_egg_radio", "targetname" ), ::radio_egg_trigger );
}

radio_egg_trigger()
{
if( !IsDefined( self ) )
return;

self waittill( "trigger", who );
who thread play_radio_egg();
}
Zombie_Theater_fx
#include maps\_utility; 
#include common_scripts\utility;

main()
{
scriptedFX();
footsteps();
maps\createart\zombie_theater_art::main();
maps\createfx\zombie_theater_fx::main();
precacheFX();
}

footsteps()
{
}

scriptedFX()
{

level._effect["animscript_gib_fx"] = LoadFx( "weapon/bullet/fx_flesh_gib_fatal_01" );
level._effect["animscript_gibtrail_fx"] = LoadFx( "trail/fx_trail_blood_streak" );

level._effect["large_ceiling_dust"] = loadfx( "maps/zombie/fx_dust_ceiling_impact_lg_mdbrown" );
level._effect["poltergeist"] = loadfx( "misc/fx_zombie_couch_effect" );

// electric switch fx
level._effect["switch_sparks"] = loadfx("env/electrical/fx_elec_wire_spark_burst");

// dogs
level._effect["dog_breath"] = loadfx("maps/zombie/fx_zombie_dog_breath");

// rise fx
level._effect["rise_burst"] = loadfx("maps/mp_maps/fx_mp_zombie_hand_dirt_burst");
level._effect["rise_billow"] = loadfx("maps/mp_maps/fx_mp_zombie_body_dirt_billowing");
level._effect["rise_dust"] = loadfx("maps/mp_maps/fx_mp_zombie_body_dust_falling");

// quad fx
level._effect["quad_grnd_dust_spwnr"] = loadfx("maps/zombie/fx_zombie_crawler_grnd_dust_spwnr");
level._effect["quad_grnd_dust"] = loadfx("maps/zombie/fx_zombie_crawler_grnd_dust");

level._effect["lght_marker"] = Loadfx("maps/zombie/fx_zombie_coast_marker");
level._effect["lght_marker_flare"] = Loadfx("maps/zombie/fx_zombie_coast_marker_fl");

//electrical trap
level._effect["electric_current"] = loadfx("misc/fx_zombie_elec_trail");
level._effect["zapper_fx"] = loadfx("misc/fx_zombie_zapper_powerbox_on");
level._effect["zapper"] = loadfx("misc/fx_zombie_electric_trap");
level._effect["zapper_wall"] = loadfx("misc/fx_zombie_zapper_wall_control_on");
level._effect["zapper_light_ready"] = loadfx("misc/fx_zombie_zapper_light_green");
level._effect["zapper_light_notready"] = loadfx("misc/fx_zombie_zapper_light_red");

level._effect["elec_md"] = loadfx("maps/zombie/fx_elec_player_md");
level._effect["elec_sm"] = loadfx("maps/zombie/fx_elec_player_sm");
level._effect["elec_torso"] = loadfx("maps/zombie/fx_elec_player_torso");

// fire trap
level._effect["fire_trap_med"] = loadfx("maps/zombie/fx_zombie_fire_trap_med");

// auto turret
level._effect["auto_turret_light"] = loadfx("maps/zombie/fx_zombie_auto_turret_light");
}

precachefx()
{

level._effect["fx_mp_smoke_thick_indoor"] = loadfx("maps/zombie/fx_mp_smoke_thick_indoor");
level._effect["fx_mp_smoke_amb_indoor_misty"] = loadfx("maps/zombie/fx_zombie_theater_smoke_amb_indoor");
level._effect["fx_smoke_smolder_md_gry"] = loadfx("maps/zombie/fx_smoke_smolder_md_gry");
level._effect["fx_smk_smolder_sm"] = loadfx("env/smoke/fx_smk_smolder_sm");
level._effect["fx_mp_smoke_crater"] = loadfx("maps/zombie/fx_mp_smoke_crater");
level._effect["fx_mp_smoke_sm_slow"] = loadfx("maps/zombie/fx_mp_smoke_sm_slow");

level._effect["fx_mp_fog_low"] = loadfx("maps/zombie/fx_mp_fog_low");
level._effect["fx_zombie_theater_fog_lg"] = loadfx("maps/zombie/fx_zombie_theater_fog_lg");
level._effect["fx_zombie_theater_fog_xlg"] = loadfx("maps/zombie/fx_zombie_theater_fog_xlg");
level._effect["fx_mp_fog_ground_md"] = loadfx("maps/mp_maps/fx_mp_fog_ground_md");

level._effect["fx_water_drip_light_long"] = loadfx("env/water/fx_water_drip_light_long");
level._effect["fx_water_drip_light_short"] = loadfx("env/water/fx_water_drip_light_short");

level._effect["fx_mp_ray_light_sm"] = loadfx("env/light/fx_light_godray_overcast_sm");
level._effect["fx_mp_ray_light_md"] = loadfx("maps/zombie/fx_mp_ray_overcast_md");
level._effect["fx_mp_ray_light_lg"] = loadfx("maps/zombie/fx_light_godray_overcast_lg");

level._effect["fx_mp_dust_motes"] = loadfx("maps/zombie/fx_mp_ray_motes_lg");
level._effect["fx_mp_dust_mote_pcloud_sm"] = loadfx("maps/zombie/fx_mp_dust_mote_pcloud_sm");
level._effect["fx_mp_dust_mote_pcloud_md"] = loadfx("maps/zombie/fx_mp_dust_mote_pcloud_md");

level._effect["fx_mp_pipe_steam"] = loadfx("env/smoke/fx_pipe_steam_md");
level._effect["fx_mp_pipe_steam_random"] = loadfx("maps/zombie/fx_mp_pipe_steam_random");
level._effect["fx_mp_fumes_vent_sm_int"] = loadfx("maps/mp_maps/fx_mp_fumes_vent_sm_int");
level._effect["fx_mp_fumes_vent_xsm_int"] = loadfx("maps/mp_maps/fx_mp_fumes_vent_xsm_int");

level._effect["fx_mp_elec_spark_burst_xsm_thin_runner"] = loadfx("maps/mp_maps/fx_mp_elec_spark_burst_xsm_thin_runner");
level._effect["fx_mp_elec_spark_burst_sm_runner"] = loadfx("maps/mp_maps/fx_mp_elec_spark_burst_sm_runner");

level._effect["fx_mp_light_lamp"] = loadfx("maps/zombie/fx_mp_light_lamp");
level._effect["fx_mp_light_corona_cool"] = loadfx("maps/zombie/fx_mp_light_corona_cool");
level._effect["fx_mp_light_corona_bulb_ceiling"] = loadfx("maps/zombie/fx_mp_light_corona_bulb_ceiling");

level._effect["fx_pent_tinhat_light"] = LoadFX("maps/pentagon/fx_pent_tinhat_light");
level._effect["fx_light_floodlight_bright"] = loadfx("maps/zombie/fx_zombie_light_floodlight_bright");
level._effect["fx_light_overhead_sm_amber"] = loadfx("maps/zombie/fx_zombie_overhead_sm_amber");
level._effect["fx_light_overhead_sm_amber_flkr"] = loadfx("maps/zombie/fx_zombie_overhead_sm_amber_flkr");
level._effect["fx_light_overhead_sm_blue"] = loadfx("maps/zombie/fx_zombie_overhead_sm_blu");
level._effect["fx_light_overhead_sm_blue_flkr"] = loadfx("maps/zombie/fx_zombie_overhead_sm_blu_flkr");

level._effect["fx_mp_birds_circling"] = loadfx("maps/zombie/fx_mp_birds_circling");
level._effect["fx_mp_insects_lantern"] = loadfx("maps/zombie/fx_mp_insects_lantern");
level._effect["fx_insects_swarm_md_light"] = loadfx("bio/insects/fx_insects_swarm_md_light");
level._effect["fx_insects_maggots"] = loadfx("bio/insects/fx_insects_maggots_sm");
level._effect["fx_insects_moths_light_source"] = loadfx("bio/insects/fx_insects_moths_light_source");
level._effect["fx_insects_moths_light_source_md"] = loadfx("bio/insects/fx_insects_moths_light_source_md");

level._effect["fx_pent_movie_projector"] = LoadFX("maps/pentagon/fx_pent_movie_projector");

level._effect["fx_zombie_light_theater_blue"] = LoadFX("maps/zombie/fx_zombie_light_theater_blue");
level._effect["fx_zombie_light_theater_green"] = LoadFX("maps/zombie/fx_zombie_light_theater_green");



// Projector Beam
level._effect["fx_zombie_theater_projector_beam"] = loadfx("maps/zombie/fx_zombie_theater_projector_beam");
level._effect["fx_zombie_theater_projector_screen"] = loadfx("maps/zombie/fx_zombie_theater_projection_screen");
// new fx for the projector screen
level._effect[ "projector_screen_0" ] = LoadFX( "maps/zombie/fx_zombie_theater_screen_0" );
level._effect[ "projector_screen_1" ] = LoadFX( "maps/zombie/fx_zombie_theater_screen_1" );
level._effect[ "projector_screen_2" ] = LoadFX( "maps/zombie/fx_zombie_theater_screen_2" );
level._effect[ "projector_screen_3" ] = LoadFX( "maps/zombie/fx_zombie_theater_screen_3" );

// Teleporter FX
level._effect["fx_transporter_beam"] = loadfx("maps/zombie/fx_transporter_beam");
level._effect["fx_transporter_pad_start"] = loadfx("maps/zombie/fx_transporter_pad_start");
level._effect["fx_transporter_start"] = loadfx("maps/zombie/fx_transporter_start");
level._effect["fx_transporter_ambient"] = loadfx("maps/zombie/fx_transporter_ambient");
level._effect["fx_zombie_mainframe_beam"] = loadfx("maps/zombie/fx_zombie_mainframe_beam");
level._effect["fx_zombie_mainframe_flat"] = loadfx("maps/zombie/fx_zombie_mainframe_flat");
level._effect["fx_zombie_mainframe_flat_start"] = loadfx("maps/zombie/fx_zombie_mainframe_flat_start");
level._effect["fx_zombie_mainframe_beam_start"] = loadfx("maps/zombie/fx_zombie_mainframe_beam_start");
level._effect["fx_zombie_flashback_theater"] = loadfx("maps/zombie/fx_zombie_flashback_theater");
level._effect["fx_zombie_difference"] = loadfx("maps/zombie/fx_zombie_difference");
level._effect["fx_zombie_heat_sink"] = loadfx("maps/zombie/fx_zombie_heat_sink");
level._effect["fx_teleporter_pad_glow"] = loadfx("maps/zombie/fx_zombie_teleporter_pad_glow");
level._effect["fx_portal"] = loadfx("maps/zombie/fx_zombie_portal_nix_num_pp");

// Pack A Punch
level._effect["zombie_packapunch"] = loadfx("maps/zombie/fx_zombie_packapunch");

// added for magic box lights
level._effect["boxlight_light_ready"] = loadfx("maps/zombie/fx_zombie_theater_lightboard_green");
level._effect["boxlight_light_notready"] = loadfx("maps/zombie/fx_zombie_theater_lightboard_red");

// Quad fx
level._effect["fx_quad_roof_break"] = loadfx("maps/zombie/fx_zombie_crawler_roof_break");
level._effect["fx_quad_roof_break_theater"] = loadfx("maps/zombie/fx_zombie_crawler_roof_theater");
level._effect["fx_quad_dust_roof"] = loadfx("maps/zombie/fx_zombie_crawler_dust_roof");
}

Zombie_Theater_Magic_Box
#include common_scripts\utility; 
#include maps\_utility;
#include maps\_zombiemode_utility;

//************************************************************************************
//
// Changes lights of Map for location
//
//************************************************************************************

magic_box_init()
{
// Array must match array in zombie_theater.csc
// Start at 'start_chest' then order clockwise - finishing in the middle.


level._BOX_INDICATOR_NO_LIGHTS = -1;
level._BOX_INDICATOR_FLASH_LIGHTS_MOVING = 99;
level._BOX_INDICATOR_FLASH_LIGHTS_FIRE_SALE = 98;

level._box_locations = array( "start_chest",
"foyer_chest",
"crematorium_chest",
"alleyway_chest",
"control_chest",
"stage_chest",
"dressing_chest",
"dining_chest",
"theater_chest");


level thread magic_box_update();
level thread watch_fire_sale();
}

get_location_from_chest_index(chest_index)
{
chest_loc = level.chests[ chest_index ].script_noteworthy;

for(i = 0; i {
if(level._box_locations[i] == chest_loc)
{
return i;
}
}

AssertMsg("Unknown chest location - " + chest_loc);
}

magic_box_update()
{
// Let the level startup
wait(2);

flag_wait( "power_on" );

// Setup
box_mode = "Box Available";

// Tell client

setclientsysstate( "box_indicator", get_location_from_chest_index(level.chest_index) );

while( 1 )
{
switch( box_mode )
{
// Waiting for the Box to Move
case "Box Available":
if( flag("moving_chest_now") )
{

// Tell client

setclientsysstate( "box_indicator", level._BOX_INDICATOR_FLASH_LIGHTS_MOVING); // flash everything.

// Next Mode
box_mode = "Box is Moving";
}
break;


case "Box is Moving":
// Waiting for the box to finish its move
while( flag("moving_chest_now") )
{
wait(0.1);
}

// Tell client
setclientsysstate( "box_indicator", get_location_from_chest_index(level.chest_index));

box_mode = "Box Available";

break;
}

wait( 0.5 );
}
}

watch_fire_sale()
{
while ( 1 )
{
level waittill( "powerup fire sale" );
setclientsysstate( "box_indicator", level._BOX_INDICATOR_FLASH_LIGHTS_FIRE_SALE ); // flash everything.

while ( level.zombie_vars["zombie_powerup_fire_sale_time"] > 0)
{
wait( 0.1 );
}

setclientsysstate( "box_indicator", get_location_from_chest_index(level.chest_index));
}
}



//ESM - added for green light/red light functionality for magic box
turnLightGreen(name, playfx)
{
zapper_lights = getentarray( name, "script_noteworthy" );

for(i=0;i {
if(isDefined(zapper_lights[i].fx))
{
zapper_lights[i].fx delete();
}

if ( isDefined( playfx ) && playfx )
{
zapper_lights[i] setmodel("zombie_zapper_cagelight_green");
zapper_lights[i].fx = maps\_zombiemode_net::network_safe_spawn( "trap_light_green", 2, "script_model", ( zapper_lights[i].origin[0], zapper_lights[i].origin[1], zapper_lights[i].origin[2] - 10 ) );
zapper_lights[i].fx setmodel("tag_origin");
zapper_lights[i].fx.angles = zapper_lights[i].angles;
playfxontag(level._effect["boxlight_light_ready"],zapper_lights[i].fx,"tag_origin");
}
else
zapper_lights[i] setmodel("zombie_zapper_cagelight");
}
}

turnLightRed(name, playfx)
{
zapper_lights = getentarray( name, "script_noteworthy" );

for(i=0;i {
if(isDefined(zapper_lights[i].fx))
{
zapper_lights[i].fx delete();
}

if ( isDefined( playfx ) && playfx )
{
zapper_lights[i] setmodel("zombie_zapper_cagelight_red");
zapper_lights[i].fx = maps\_zombiemode_net::network_safe_spawn( "trap_light_red", 2, "script_model", ( zapper_lights[i].origin[0], zapper_lights[i].origin[1], zapper_lights[i].origin[2] - 10 ) );
zapper_lights[i].fx setmodel("tag_origin");
zapper_lights[i].fx.angles = zapper_lights[i].angles;
playfxontag(level._effect["boxlight_light_notready"],zapper_lights[i].fx,"tag_origin");
}
else
zapper_lights[i] setmodel("zombie_zapper_cagelight");
}
}

more coming...

Link to comment

Zombiemode_Audio

#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include maps\_music;
#include maps\_busing;

audio_init()
{
level init_audio_aliases();
level init_music_states();
level thread init_audio_functions();
}

//All Vox should be found in this section.
//If there is an Alias that needs to be changed, check here first.
init_audio_aliases()
{
//**Announcer Vox Categories**\\
//ARRAY and PREFIX: Setting up a prefix and array for all Devil lines
level.devil_vox = [];
level.devil_vox["prefix"] = "zmb_vox_ann_";

//POWERUPS: Play after a player picks up a powerup; plays for ALL players
level.devil_vox["powerup"] = [];
level.devil_vox["powerup"]["carpenter"] = "carpenter";
level.devil_vox["powerup"]["insta_kill"] = "instakill";
level.devil_vox["powerup"]["double_points"] = "doublepoints";
level.devil_vox["powerup"]["nuke"] = "nuke";
level.devil_vox["powerup"]["full_ammo"] = "maxammo";
level.devil_vox["powerup"]["fire_sale"] = "firesale";
level.devil_vox["powerup"]["fire_sale_short"] = "firesale_short";
level.devil_vox["powerup"]["minigun"] = "death_machine";
level.devil_vox["powerup"]["bonfire_sale"] = "bonfiresale";
level.devil_vox["powerup"]["all_revive"] = undefined;

//**Player Zombie Vox Categories**\\
//ARRAY and PREFIX: Creating the main player vox array, setting up the default alias prefix that will be added onto all lines
level.plr_vox = [];
level.plr_vox["prefix"] = "vox_plr_";

//GENERAL: Any lines that do not fit into an overall larger category.
level.plr_vox["general"] = [];
level.plr_vox["general"]["crawl_spawn"] = "spawn_crawl"; //OCCURS WHEN THE PLAYER SHOOTS THE LEGS OFF A ZOMBIE, CREATING A CRAWLER
level.plr_vox["general"]["crawl_spawn_response"] = "resp_spawn_crawl"; //RESPONSE TO ABOVE
level.plr_vox["general"]["dog_spawn"] = "spawn_dog"; //OCCURS AT THE BEGINNING OF A DOG ROUND
level.plr_vox["general"]["dog_spawn_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["quad_spawn"] = "spawn_quad"; //OCCURS WHEN QUADS FIRST SPAWN THROUGH THE ROOF
level.plr_vox["general"]["quad_spawn_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["ammo_low"] = "ammo_low"; //OCCURS WHEN THE PLAYERS AMMO IN A WEAPON IS BELOW 5
level.plr_vox["general"]["ammo_low_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["ammo_out"] = "ammo_out"; //OCCURS WHEN THE PLAYER HAS NO MORE AMMO FOR A WEAPON
level.plr_vox["general"]["ammo_out_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["door_deny"] = "nomoney"; //CURRENTLY UNUSED: INTENDED FOR LOCKED, POWER-DRIVEN DOORS
level.plr_vox["general"]["door_deny_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["perk_deny"] = "nomoney"; //OCCURS WHEN THE PLAYER CANNOT AFFORD A PERK OR ALREADY HAS THE PERK
level.plr_vox["general"]["perk_deny_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["intro"] = "level_start"; //CURRENTLY UNUSED: INTENDED AS THE FIRST LINE WHEN THE GAME BEGINS
level.plr_vox["general"]["intro_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["shoot_arm"] = "shoot_limb"; //OCCURS WHEN THE PLAYER SHOOTS OFF AN ARM
level.plr_vox["general"]["shoot_arm_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["box_move"] = "box_move"; //OCCURS WHEN THE PLAYER CAUSES THE MAGIC BOX TO CHANGE POSITION
level.plr_vox["general"]["box_move_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["no_money"] = "nomoney"; //OCCURS WHEN THE PLAYER HAS NO MONEY AND TRIES TO BUY A WEAPON
level.plr_vox["general"]["no_money_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["oh_shit"] = "ohshit"; //OCCURS WHEN 4 OR MORE ZOMBIES ARE WITHIN 250 UNITS OF THE PLAYER
level.plr_vox["general"]["oh_shit_response"] = "resp_ohshit"; //RESPONSE TO ABOVE
level.plr_vox["general"]["revive_down"] = "revive_down"; //OCCURS WHEN THE PLAYER GOES INTO LAST STAND
level.plr_vox["general"]["revive_down_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["revive_up"] = "revive_up"; //OCCURS WHEN THE PLAYER REVIVES A TEAMMATE
level.plr_vox["general"]["revive_up_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["crawl_hit"] = "crawler_hit"; //OCCURS WHEN THE PLAYER IS HIT BY A CRAWLER
level.plr_vox["general"]["crawl_hit_response"] = undefined; //RESPONSE TO ABOVE

//PERKS: Play whenever a player buys a perk.
level.plr_vox["perk"] = [];
level.plr_vox["perk"]["specialty_armorvest"] = "perk_jugga"; //JUGGERNOG PURCHASE
level.plr_vox["perk"]["specialty_armorvest_response"] = undefined; //JUGGERNOG PURCHASE RESPONSE
level.plr_vox["perk"]["specialty_quickrevive"] = "perk_revive"; //REVIVE SODA PURCHASE
level.plr_vox["perk"]["specialty_quickrevive_response"] = undefined; //REVIVE SODA PURCHASE RESPONSE
level.plr_vox["perk"]["specialty_fastreload"] = "perk_speed"; //SPEED COLA PURCHASE
level.plr_vox["perk"]["specialty_fastreload_response"] = undefined; //SPEED COLA PURCHASE RESPONSE
level.plr_vox["perk"]["specialty_rof"] = "perk_doubletap"; //DOUBLETAP ROOTBEER PURCHASE
level.plr_vox["perk"]["specialty_rof_response"] = undefined; //DOUBLETAP ROOTBEER PURCHASE RESPONSE

//POWERUPS: Play whenever a player picks up a powerup
level.plr_vox["powerup"] = [];
level.plr_vox["powerup"]["nuke"] = "powerup_nuke"; //NUKE PICKUP
level.plr_vox["powerup"]["nuke_response"] = undefined; //NUKE PICKUP RESPONSE
level.plr_vox["powerup"]["insta_kill"] = "powerup_insta"; //INSTA-KILL PICKUP
level.plr_vox["powerup"]["insta_kill_response"] = undefined; //INSTA-KILL PICKUP RESPONSE
level.plr_vox["powerup"]["full_ammo"] = "powerup_ammo"; //MAX AMMO PICKUP
level.plr_vox["powerup"]["full_ammo_response"] = undefined; //MAX AMMO PICKUP RESPONSE
level.plr_vox["powerup"]["double_points"] = "powerup_double"; //DOUBLE POINTS PICKUP
level.plr_vox["powerup"]["double_points_response"] = undefined; //DOUBLE POINTS PICKUP RESPONSE
level.plr_vox["powerup"]["carpenter"] = "powerup_carp"; //CARPENTER PICKUP
level.plr_vox["powerup"]["carpenter_response"] = undefined; //CARPENTER RESPONSE
level.plr_vox["powerup"]["firesale"] = "powerup_firesale"; //FIRESALE PICKUP
level.plr_vox["powerup"]["firesale_response"] = undefined; //FIRESALE RESPONSE

//WEAPON KILLS: Plays whenever certain Kill Criteria are met
level.plr_vox["kill"] = [];
level.plr_vox["kill"]["melee"] = "kill_melee"; //PLAYER KILLS A ZOMBIE USING MELEE
level.plr_vox["kill"]["melee_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["melee_instakill"] = "kill_insta"; //PLAYER KILLS A ZOMBIE USING MELEE WHILE INSTAKILL IS ACTIVE
level.plr_vox["kill"]["melee_instakill_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["weapon_instakill"] = "kill_insta"; //PLAYER KILLS A ZOMBIE USING ANY WEAPON WHILE INSTAKILL IS ACTIVE
level.plr_vox["kill"]["weapon_instakill_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["closekill"] = "kill_close"; //PLAYER KILLS A ZOMBIE WHO IS WITHIN 64 UNITS OF THE PLAYER
level.plr_vox["kill"]["closekill_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["damage"] = "kill_damaged"; //WHEN THE PLAYER KILLS A ZOMBIE AFTER RECEIVING DAMAGE FROM SAID ZOMBIE
level.plr_vox["kill"]["damage_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["streak"] = "kill_streak"; //OCCURS WHEN THE PLAYER KILLS OVER 6 ZOMBIES WITHIN A SMALL TIME PERIOD
level.plr_vox["kill"]["streak_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["headshot"] = "kill_headshot"; //PLAYER KILLS A ZOMBIE WITH A HEADSHOT OVER 400 UNITS AWAY
level.plr_vox["kill"]["headshot_response"] = "resp_kill_headshot"; //RESPONSE TO ABOVE
level.plr_vox["kill"]["explosive"] = "kill_explo"; //PLAYER KILLS A ZOMBIE USING EXPLOSIVES
level.plr_vox["kill"]["explosive_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["flame"] = "kill_flame"; //PLAYER KILLS A ZOMBIE USING FLAME
level.plr_vox["kill"]["flame_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["raygun"] = "kill_ray"; //PLAYER KILLS A ZOMBIE USING THE RAYGUN
level.plr_vox["kill"]["raygun_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["bullet"] = "kill_streak"; //PLAYER KILLS A ZOMBIE USING ANY BULLET BASED WEAPON
level.plr_vox["kill"]["bullet_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["tesla"] = "kill_tesla"; //PLAYER KILLS 4 OR MORE ZOMBIES WITH ONE SHOT OF THE TESLA GUN
level.plr_vox["kill"]["tesla_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["monkey"] = "kill_monkey"; //WHEN THE PLAYER KILLS A ZOMBIE USING THE MONKEYBOMB
level.plr_vox["kill"]["monkey_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["thundergun"] = "kill_thunder"; //PLAYER KILLS A ZOMBIE USING THE THUNDERGUN
level.plr_vox["kill"]["thundergun_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["freeze"] = "kill_freeze"; //PLAYER KILLS A ZOMBIE USING THE FREEZEGUN
level.plr_vox["kill"]["freeze_response"] = undefined;
level.plr_vox["kill"]["crawler"] = "kill_crawler"; //PLAYER KILLS A CRAWLING ZOMBIE
level.plr_vox["kill"]["crawler_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["hellhound"] = "kill_hellhound"; //PLAYER KILLS A HELLHOUND
level.plr_vox["kill"]["hellhound_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["quad"] = "kill_quad"; //PLAYER KILLS A QUAD ZOMBIE
level.plr_vox["kill"]["quad_response"] = undefined; //RESPONSE TO ABOVE

//WEAPON PICKUPS: Each will play after the Player buys or gets a weapon from the box. Broken into weapon categories.
//Can be made weapon specific, if the need arises.
level.plr_vox["weapon_pickup"] = [];
level.plr_vox["weapon_pickup"]["pistol"] = "wpck_crappy";
level.plr_vox["weapon_pickup"]["pistol_response"] = undefined;
level.plr_vox["weapon_pickup"]["smg"] = "wpck_smg";
level.plr_vox["weapon_pickup"]["smg_response"] = undefined;
level.plr_vox["weapon_pickup"]["dualwield"] = "wpck_dual";
level.plr_vox["weapon_pickup"]["dualwield_response"] = undefined;
level.plr_vox["weapon_pickup"]["shotgun"] = "wpck_shotgun";
level.plr_vox["weapon_pickup"]["shotgun_response"] = undefined;
level.plr_vox["weapon_pickup"]["rifle"] = "wpck_sniper";
level.plr_vox["weapon_pickup"]["rifle_response"] = undefined;
level.plr_vox["weapon_pickup"]["burstrifle"] = "wpck_mg";
level.plr_vox["weapon_pickup"]["burstrifle_response"] = undefined;
level.plr_vox["weapon_pickup"]["assault"] = "wpck_mg";
level.plr_vox["weapon_pickup"]["assault_response"] = undefined;
level.plr_vox["weapon_pickup"]["sniper"] = "wpck_sniper";
level.plr_vox["weapon_pickup"]["sniper_response"] = undefined;
level.plr_vox["weapon_pickup"]["mg"] = "wpck_mg";
level.plr_vox["weapon_pickup"]["mg_response"] = undefined;
level.plr_vox["weapon_pickup"]["launcher"] = "wpck_launcher";
level.plr_vox["weapon_pickup"]["launcher_response"] = undefined;
level.plr_vox["weapon_pickup"]["grenade"] = "wpck_crappy";
level.plr_vox["weapon_pickup"]["grenade_response"] = undefined;
level.plr_vox["weapon_pickup"]["bowie"] = "wpck_bowie";
level.plr_vox["weapon_pickup"]["bowie_response"] = undefined;
level.plr_vox["weapon_pickup"]["raygun"] = "wpck_raygun";
level.plr_vox["weapon_pickup"]["raygun_response"] = undefined;
level.plr_vox["weapon_pickup"]["monkey"] = "wpck_monkey";
level.plr_vox["weapon_pickup"]["monkey_response"] = "resp_wpck_monkey";
level.plr_vox["weapon_pickup"]["tesla"] = "wpck_tesla";
level.plr_vox["weapon_pickup"]["tesla_response"] = undefined;
level.plr_vox["weapon_pickup"]["thunder"] = "wpck_thunder";
level.plr_vox["weapon_pickup"]["thunder_response"] = undefined;
level.plr_vox["weapon_pickup"]["freezegun"] = "wpck_freeze";
level.plr_vox["weapon_pickup"]["freezegun_response"] = undefined;
level.plr_vox["weapon_pickup"]["crossbow"] = "wpck_launcher";
level.plr_vox["weapon_pickup"]["crossbow_response"] = undefined;
level.plr_vox["weapon_pickup"]["upgrade"] = "wpck_upgrade";
level.plr_vox["weapon_pickup"]["upgrade_response"] = undefined;
level.plr_vox["weapon_pickup"]["upgrade_wait"] = "wpck_upgrade_wait";
level.plr_vox["weapon_pickup"]["upgrade_wait_response"] = undefined;
level.plr_vox["weapon_pickup"]["favorite"] = "wpck_favorite";
level.plr_vox["weapon_pickup"]["favorite_response"] = undefined;
level.plr_vox["weapon_pickup"]["favorite_upgrade"] = "wpck_favorite_upgrade";
level.plr_vox["weapon_pickup"]["favorite_upgrade_response"] = undefined;

//EGGS and OTHER STUFF: Egg lines, achievements, etc
level.plr_vox["eggs"] = [];
level.plr_vox["eggs"]["achievement"] = "achievement";
level.plr_vox["eggs"]["music_activate"] = "secret";
level.plr_vox["eggs"]["meteors"] = "egg_pedastool";
level.plr_vox["eggs"]["room_screen"] = "egg_room_screen";
level.plr_vox["eggs"]["room_dress"] = "egg_room_dress";
level.plr_vox["eggs"]["room_lounge"] = "egg_room_lounge";
level.plr_vox["eggs"]["room_rest"] = "egg_room_rest";
level.plr_vox["eggs"]["room_alley"] = "egg_room_alley";
level.plr_vox["eggs"]["portrait_dempsey"] = "egg_port_dempsey";
level.plr_vox["eggs"]["portrait_nikolai"] = "egg_port_nikolai";
level.plr_vox["eggs"]["portrait_takeo"] = "egg_port_takeo";
level.plr_vox["eggs"]["portrait_richtofan"] = "egg_port_richtofan";
level.plr_vox["eggs"]["portrait_empty"] = "egg_port_empty";

//**ZOMBIE VOCALIZATIONS**\\
//ARRAY and PREFIX: Setting up a prefix and array for all Zombie vocalizations
level.zmb_vox = [];
level.zmb_vox["prefix"] = "zmb_vocals_";

//Standard Zombies
level.zmb_vox["zombie"] = [];
level.zmb_vox["zombie"]["ambient"] = "zombie_ambience";
level.zmb_vox["zombie"]["sprint"] = "zombie_sprint";
level.zmb_vox["zombie"]["attack"] = "zombie_attack";
level.zmb_vox["zombie"]["teardown"] = "zombie_teardown";
level.zmb_vox["zombie"]["taunt"] = "zombie_taunt";
level.zmb_vox["zombie"]["behind"] = "zombie_behind";
level.zmb_vox["zombie"]["death"] = "zombie_death";
level.zmb_vox["zombie"]["crawler"] = "zombie_crawler";

//Quad Zombies
level.zmb_vox["quad_zombie"] = [];
level.zmb_vox["quad_zombie"]["ambient"] = "quad_ambience";
level.zmb_vox["quad_zombie"]["sprint"] = "quad_sprint";
level.zmb_vox["quad_zombie"]["attack"] = "quad_attack";
level.zmb_vox["quad_zombie"]["behind"] = "quad_behind";
level.zmb_vox["quad_zombie"]["death"] = "quad_death";

//Thief Zombies
level.zmb_vox["thief_zombie"] = [];
level.zmb_vox["thief_zombie"]["ambient"] = "thief_ambience";
level.zmb_vox["thief_zombie"]["sprint"] = "thief_sprint";
level.zmb_vox["thief_zombie"]["steal"] = "thief_steal";
level.zmb_vox["thief_zombie"]["death"] = "thief_death";
level.zmb_vox["thief_zombie"]["anger"] = "thief_anger";

//Boss Zombies
level.zmb_vox["boss_zombie"] = [];
level.zmb_vox["boss_zombie"]["ambient"] = "boss_ambience";
level.zmb_vox["boss_zombie"]["sprint"] = "boss_sprint";
level.zmb_vox["boss_zombie"]["attack"] = "boss_attack";
level.zmb_vox["boss_zombie"]["behind"] = "boss_behind";
level.zmb_vox["boss_zombie"]["death"] = "boss_death";

}

init_audio_functions()
{
flag_wait( "all_players_connected" );

players = get_players();
for( i = 0; i {
players[i] thread zombie_behind_vox();
players[i] thread player_killstreak_timer();
players[i] thread oh_shit_vox();
}
}

//Plays a specific Zombie vocal when they are close behind the player
//Self is the Player(s)
zombie_behind_vox()
{
self endon("disconnect");
self endon("death");

while(1)
{
wait(1);

zombs = GetAISpeciesArray("axis");

for(i=0;i {
if(!isDefined(zombs[i]))
{
continue;
}

if(zombs[i].isdog)
{
continue;
}

dist = 200;
z_dist = 50;
alias = level.vox_behind_zombie;

if(IsDefined(zombs[i].zombie_move_speed))
{
switch(zombs[i].zombie_move_speed)
{
case "walk": dist = 200;break;
case "run": dist = 250;break;
case "sprint": dist = 275;break;
}
}
if(DistanceSquared(zombs[i].origin,self.origin) {
yaw = self animscripts\utility::GetYawToSpot(zombs[i].origin );
z_diff = self.origin[2] - zombs[i].origin[2];
if( (yaw 95) && abs( z_diff ) {
zombs[i] thread maps\_zombiemode_audio::do_zombies_playvocals( "behind", zombs[i].animname );
}
}
}
}
}

do_zombies_playvocals( alias_type, zombie_type )
{
self endon( "death" );

if( !IsDefined( zombie_type ) )
{
zombie_type = "zombie";
}

if( !IsDefined( self.talking ) )
{
self.talking = false;
}

//DEBUG SECTION
if( !IsDefined( level.zmb_vox[zombie_type] ) )
{
/#
IPrintLnBold( "AUDIO - ZOMBIE TYPE: " + zombie_type + " has NO aliases set up for it." );
#/
return;
}

if( !IsDefined( level.zmb_vox[zombie_type][alias_type] ) )
{
/#
IPrintLnBold( "AUDIO - ZOMBIE TYPE: " + zombie_type + " has NO aliases set up for ALIAS_TYPE: " + alias_type );
#/
return;
}

alias = level.zmb_vox["prefix"] + level.zmb_vox[zombie_type][alias_type];

if( alias_type == "attack" || alias_type == "behind" || alias_type == "death" || alias_type == "anger" || alias_type == "steal" )
{
self PlaySound( alias );
}
else if( !self.talking )
{
self.talking = true;
self PlaySound( alias, "sounddone" );
self waittill( "sounddone" );
self.talking = false;
}
}

oh_shit_vox()
{
self endon("disconnect");
self endon("death");

while(1)
{
wait(1);

players = getplayers();
zombs = GetAISpeciesArray("axis");

if( players.size > 1 )
{
close_zombs = 0;
for( i=0; i {
if( DistanceSquared( zombs[i].origin, self.origin ) {
close_zombs ++;
}
}
if( close_zombs > 4 )
{
if( randomintrange( 0, 20 ) {
self create_and_play_dialog( "general", "oh_shit" );
}
}
}
}
}

//**Player Dialog - The following functions all serve to play Player dialog
//**To use create_and_play_dialog, _zombiemode_audio must be included in the GSC you're using the function in, or you must
//**call the function like so: player maps\_zombiemode_audio::create_and_play_dialog()

create_and_play_dialog( category, type, response, force_variant )
{
waittime = .25;

/#
if( GetDvarInt( #"debug_audio" ) > 0 )
level thread dialog_debugger( category, type );
#/

if( !IsDefined( level.plr_vox[category][type] ) )
{
//IPrintLnBold( "No Category: " + category + " and Type: " + type );
return;
}

alias_suffix = level.plr_vox[category][type];

if( IsDefined( response ) )
alias_suffix = response + alias_suffix;

index = maps\_zombiemode_weapons::get_player_index(self);
prefix = level.plr_vox["prefix"] + index + "_";

if( !IsDefined ( self.sound_dialog ) )
{
self.sound_dialog = [];
self.sound_dialog_available = [];
}

if ( !IsDefined ( self.sound_dialog[ alias_suffix ] ) )
{
num_variants = maps\_zombiemode_spawner::get_number_variants( prefix + alias_suffix );

//TOOK OUT THE ASSERT AND ADDED THIS CHECK FOR LOCS
if( num_variants {
return;
}
//assertex( num_variants > 0, "No dialog variants found for category: " + alias_suffix );

for( i = 0; i {
self.sound_dialog[ alias_suffix ][ i ] = i;
}

self.sound_dialog_available[ alias_suffix ] = [];
}

if ( self.sound_dialog_available[ alias_suffix ].size {
self.sound_dialog_available[ alias_suffix ] = self.sound_dialog[ alias_suffix ];
}

variation = random( self.sound_dialog_available[ alias_suffix ] );
self.sound_dialog_available[ alias_suffix ] = array_remove( self.sound_dialog_available[ alias_suffix ], variation );

if( IsDefined( force_variant ) )
{
variation = force_variant;
}

sound_to_play = alias_suffix + "_" + variation;

self thread do_player_playvox( prefix, index, sound_to_play, waittime, category, type );
}

do_player_playvox( prefix, index, sound_to_play, waittime, category, type )
{
if( !IsDefined( level.player_is_speaking ) )
{
level.player_is_speaking = 0;
}
if( level.player_is_speaking != 1 )
{
level.player_is_speaking = 1;
self playsound( prefix + sound_to_play, "sound_done" + sound_to_play );
self waittill( "sound_done" + sound_to_play );
wait( waittime );
level.player_is_speaking = 0;
if( isdefined( level.plr_vox[category][type + "_response"] ) )
{
level thread setup_response_line( self, index, category, type );
}
}
}

setup_response_line( player, index, category, type )
{
Dempsey = 0;
Nikolai = 1;
Takeo = 2;
Richtofen = 3;

switch( index )
{
case 0:
level setup_hero_rival( player, Takeo, Richtofen, category, type );
break;

case 1:
level setup_hero_rival( player, Richtofen, Takeo, category, type );
break;

case 2:
level setup_hero_rival( player, Dempsey, Nikolai, category, type );
break;

case 3:
level setup_hero_rival( player, Nikolai, Dempsey, category, type );
break;
}
return;
}

setup_hero_rival( player, hero, rival, category, type )
{
players = getplayers();

playHero = isdefined(players[hero]);
playRival = isdefined(players[rival]);

if(playHero && playRival)
{
if(randomfloatrange(0,1) {
playRival = false;
}
else
{
playHero = false;
}
}
if( playHero )
{
if( distancesquared (player.origin, players[hero].origin) {
players[hero] create_and_play_dialog( category, type + "_response", "hr_" );
}
else if( isdefined( players[rival] ) )
{
playRival = true;
}
}
if( playRival )
{
if( distancesquared (player.origin, players[rival].origin) {
players[rival] create_and_play_dialog( category, type + "_response", "riv_" );
}
}
}

//For any 2d Announcer Line
do_announcer_playvox( category )
{
if( !IsDefined( category ) )
return;

if( !IsDefined( level.devil_is_speaking ) )
{
level.devil_is_speaking = 0;
}

alias = level.devil_vox["prefix"] + category;

if( level.devil_is_speaking == 0 )
{
level.devil_is_speaking = 1;
level play_sound_2D( alias );
wait 2.0;
level.devil_is_speaking =0;
}
}

//** Player Killstreaks: The following functions start a timer on each player whenever they begin killing zombies.
//** If they kill a certain amount of zombies within a certain time, they will get a Killstreak line
player_killstreak_timer()
{
self endon("disconnect");
self endon("death");

if(getdvar ("zombie_kills") == "")
{
setdvar ("zombie_kills", "7");
}
if(getdvar ("zombie_kill_timer") == "")
{
setdvar ("zombie_kill_timer", "5");
}

kills = GetDvarInt( #"zombie_kills");
time = GetDvarInt( #"zombie_kill_timer");

if (!isdefined (self.timerIsrunning))
{
self.timerIsrunning = 0;
}

while(1)
{
self waittill("zom_kill");
self.killcounter ++;

if (self.timerIsrunning != 1)
{
self.timerIsrunning = 1;
self thread timer_actual(kills, time);
}
}
}

player_zombie_kill_vox( hit_location, player, mod, zombie )
{
weapon = player GetCurrentWeapon();
dist = DistanceSquared( player.origin, zombie.origin );

if( !isdefined(level.zombie_vars["zombie_insta_kill"] ) )
level.zombie_vars["zombie_insta_kill"] = 0;

instakill = level.zombie_vars["zombie_insta_kill"];

death = get_mod_type( hit_location, mod, weapon, zombie, instakill, dist );
chance = get_mod_chance( death );

if( chance > RandomIntRange( 1, 100 ) )
{
player create_and_play_dialog( "kill", death );
}
}

get_mod_chance( meansofdeath )
{
chance = undefined;

switch( meansofdeath )
{
case "melee": chance = 75; break;
case "melee_instakill": chance = 99; break;
case "weapon_instakill": chance = 10; break;
case "explosive": chance = 60; break;
case "flame": chance = 60; break;
case "raygun": chance = 75; break;
case "headshot": chance = 99; break;
case "crawler": chance = 30; break;
case "quad": chance = 30; break;
case "closekill": chance = 15; break;
case "bullet": chance = 10; break;
case "default": chance = 10; break;
}
return chance;
}

get_mod_type( impact, mod, weapon, zombie, instakill, dist )
{
close_dist = 64 * 64;
far_dist = 400 * 400;

//MELEE & MELEE_INSTAKILL
if( ( mod == "MOD_MELEE" ||
mod == "MOD_BAYONET" ||
mod == "MOD_UNKNOWN" ) &&
dist {
if( !instakill )
return "melee";
else
return "melee_instakill";
}

//EXPLOSIVE & EXPLOSIVE_INSTAKILL
if( ( mod == "MOD_GRENADE" ||
mod == "MOD_GRENADE_SPLASH" ||
mod == "MOD_PROJECTILE_SPLASH" ||
mod == "MOD_EXPLOSIVE" ) &&
weapon != "ray_gun_zm" )
{
if( !instakill )
return "explosive";
else
return "weapon_instakill";
}

//FLAME & FLAME_INSTAKILL
if( ( IsSubStr( weapon, "flame" ) ||
IsSubStr( weapon, "molotov_" ) ||
IsSubStr( weapon, "napalmblob_" ) ) &&
( mod == "MOD_BURNED" ||
mod == "MOD_GRENADE" ||
mod == "MOD_GRENADE_SPLASH" ) )
{
if( !instakill )
return "flame";
else
return "weapon_instakill";
}

//RAYGUN & RAYGUN_INSTAKILL
if( weapon == "ray_gun_zm" &&
dist > far_dist )
{
if( !instakill )
return "raygun";
else
return "weapon_instakill";
}

//HEADSHOT
if( ( mod == "MOD_RIFLE_BULLET" ||
mod == "MOD_PISTOL_BULLET" ) &&
( impact == "head" &&
dist > far_dist &&
!instakill ) )
{
return "headshot";
}

//QUAD
if( mod != "MOD_MELEE" &&
impact != "head" &&
zombie.animname == "quad_zombie" &&
!instakill )
{
return "quad";
}

//CRAWLER
if( mod != "MOD_MELEE" &&
impact != "head" &&
!zombie.has_legs &&
!instakill )
{
return "crawler";
}

//CLOSEKILL
if( mod != "MOD_BURNED" &&
dist !instakill )
{
return "closekill";
}

//BULLET & BULLET_INSTAKILL
if( mod == "MOD_RIFLE_BULLET" ||
mod == "MOD_PISTOL_BULLET" )
{
if( !instakill )
return "bullet";
else
return "weapon_instakill";
}

return "default";
}

timer_actual(kills, time)
{
self endon("disconnect");
self endon("death");

timer = gettime() + (time * 1000);
while(getTime() {
if (self.killcounter > kills)
{
self create_and_play_dialog( "kill", "streak" );

wait(1);

//resets the killcounter and the timer
self.killcounter = 0;

timer = -1;
}
wait(0.1);
}
self.killcounter = 0;
self.timerIsrunning = 0;
}

perks_a_cola_jingle_timer()
{
self thread play_random_broken_sounds();
while(1)
{
//wait(randomfloatrange(60, 120));
wait(randomfloatrange(31,45));
if(randomint(100) {
self thread play_jingle_or_stinger(self.script_sound);

}
}
}

play_jingle_or_stinger( perksacola )
{
playsoundatposition ("evt_electrical_surge", self.origin);
if(!IsDefined (self.jingle_is_playing ))
{
self.jingle_is_playing = 0;
}
if (IsDefined ( perksacola ))
{
if(self.jingle_is_playing == 0 && level.music_override == false)
{
self.jingle_is_playing = 1;
self playsound ( perksacola, "sound_done");
self waittill ("sound_done");
self.jingle_is_playing = 0;
}
}
}

play_random_broken_sounds()
{
level endon ("jingle_playing");
if (!isdefined (self.script_sound))
{
self.script_sound = "null";
}
if (self.script_sound == "mus_perks_revive_jingle")
{
while(1)
{
wait(randomfloatrange(7, 18));
playsoundatposition ("zmb_perks_broken_jingle", self.origin);
//playfx (level._effect["electric_short_oneshot"], self.origin);
playsoundatposition ("evt_electrical_surge", self.origin);

}
}
else
{
while(1)
{
wait(randomfloatrange(7, 18));
// playfx (level._effect["electric_short_oneshot"], self.origin);
playsoundatposition ("evt_electrical_surge", self.origin);
}
}
}

//SELF = Player Buying Perk
perk_vox( perk )
{
//Delay to prevent an early speech
wait( 1.5 );
if( !IsDefined( level.plr_vox["perk"][perk] ) )
{
/#
IPrintLnBold( perk + " has no PLR VOX category set up." );
#/
return;
}
self create_and_play_dialog( "perk", perk );
}

dialog_debugger( category, type )
{
/#
PrintLn( "DIALOG DEBUGGER: Category - " + category + " Type - " + type + " Response - " + type + "_response" );

if( !IsDefined( level.plr_vox[category][type] ) )
{
IPrintLnBold( "Player tried to play a line, but no alias exists. Category: " + category + " Type: " + type );
PrintLn( "DIALOG DEBUGGER ERROR: Alias Not Defined For " + category + " " + type );
}

if( !IsDefined( level.plr_vox[category][type + "_response" ] ) )
PrintLn( "DIALOG DEBUGGER ERROR: Response Alias Not Defined For " + category + " " + type + "_response" );
#/
}

//MUSIC STATES
init_music_states()
{
level.music_override = false;
level.music_round_override = false;

level.zmb_music_states = [];
level.zmb_music_states["round_start"] = spawnStruct();
level.zmb_music_states["round_start"].music = "mus_zombie_round_start";
level.zmb_music_states["round_start"].is_alias = true;
level.zmb_music_states["round_start"].override = true;
level.zmb_music_states["round_start"].round_override = true;
level.zmb_music_states["round_start"].musicstate = "WAVE";
level.zmb_music_states["round_end"] = spawnStruct();
level.zmb_music_states["round_end"].music = "mus_zombie_round_over";
level.zmb_music_states["round_end"].is_alias = true;
level.zmb_music_states["round_end"].override = true;
level.zmb_music_states["round_end"].round_override = true;
level.zmb_music_states["round_end"].musicstate = "SILENCE";
level.zmb_music_states["wave_loop"] = spawnStruct();
level.zmb_music_states["wave_loop"].music = "WAVE";
level.zmb_music_states["wave_loop"].is_alias = false;
level.zmb_music_states["wave_loop"].override = true;
level.zmb_music_states["game_over"] = spawnStruct();
level.zmb_music_states["game_over"].music = "mus_zombie_game_over";
level.zmb_music_states["game_over"].is_alias = true;
level.zmb_music_states["game_over"].override = false;
level.zmb_music_states["game_over"].musicstate = "SILENCE";
level.zmb_music_states["dog_start"] = spawnStruct();
level.zmb_music_states["dog_start"].music = "mus_zombie_dog_start";
level.zmb_music_states["dog_start"].is_alias = true;
level.zmb_music_states["dog_start"].override = true;
level.zmb_music_states["dog_end"] = spawnStruct();
level.zmb_music_states["dog_end"].music = "mus_zombie_dog_end";
level.zmb_music_states["dog_end"].is_alias = true;
level.zmb_music_states["dog_end"].override = true;
level.zmb_music_states["egg"] = spawnStruct();
level.zmb_music_states["egg"].music = "EGG";
level.zmb_music_states["egg"].is_alias = false;
level.zmb_music_states["egg"].override = false;
level.zmb_music_states["egg_safe"] = spawnStruct();
level.zmb_music_states["egg_safe"].music = "EGG_SAFE";
level.zmb_music_states["egg_safe"].is_alias = false;
level.zmb_music_states["egg_safe"].override = false;
}

change_zombie_music( state )
{
wait(.05);

m = level.zmb_music_states[state];

if( !IsDefined( m ) )
{
/#
IPrintLnBold( "Called change_zombie_music on undefined state: " + state );
#/
return;
}

if( !IsDefined( m.round_override ) )
m.round_override = false;

if( m.override == true && level.music_override == true )
return;

if( m.round_override == true && level.music_round_override == true )
return;

if( m.is_alias )
{
if( IsDefined( m.musicstate ) )
setmusicstate( m.musicstate );

play_sound_2d( m.music );
}
else
{
setmusicstate( m.music );
}
}

(this one is huge...more coming)

Link to comment

_Zombiemode (Please note, this one is too large to post in one post...it is continued in the next two replies to this)

#include maps\_anim; 
#include maps\_utility;
#include common_scripts\utility;
#include maps\_music;
#include maps\_zombiemode_utility;
#include maps\_busing;

#using_animtree( "generic_human" );

main()
{
level.zombiemode = true;
level.reviveFeature = false;
level.contextualMeleeFeature = false;
level.swimmingFeature = false;

level.zombie_visionset = "zombie_neutral";

precache_shaders();
precache_models();

PrecacheItem( "frag_grenade_zm" );
PrecacheItem( "claymore_zm" );

//override difficulty
level.skill_override = 1;
maps\_gameskill::setSkill(undefined,level.skill_override);

level._ZOMBIE_GIB_PIECE_INDEX_ALL = 0;
level._ZOMBIE_GIB_PIECE_INDEX_RIGHT_ARM = 1;
level._ZOMBIE_GIB_PIECE_INDEX_LEFT_ARM = 2;
level._ZOMBIE_GIB_PIECE_INDEX_RIGHT_LEG = 3;
level._ZOMBIE_GIB_PIECE_INDEX_LEFT_LEG = 4;
level._ZOMBIE_GIB_PIECE_INDEX_HEAD = 5;
level._ZOMBIE_GIB_PIECE_INDEX_GUTS = 6;

init_dvars();
init_mutators();
init_strings();
init_levelvars();
init_animscripts();
init_sounds();
init_shellshocks();
init_flags();
init_client_flags();

//Limit zombie to 24 max, must have for network purposes
SetAILimit( 24 );

init_fx();
//maps\_zombiemode_ability::init();

// load map defaults
maps\_zombiemode_load::main();

// Initialize the zone manager above any scripts that make use of zone info
maps\_zombiemode_zone_manager::init();

// Call the other zombiemode scripts
maps\_zombiemode_audio::audio_init();
//maps\_zombiemode_challenges::init();
maps\_zombiemode_claymore::init();
maps\_zombiemode_weapons::init();
maps\_zombiemode_blockers::init();
maps\_zombiemode_spawner::init();
maps\_zombiemode_powerups::init();
maps\_zombiemode_perks::init();
maps\_zombiemode_user::init();
maps\_zombiemode_weap_cymbal_monkey::init();
maps\_zombiemode_weap_freezegun::init();
maps\_zombiemode_weap_tesla::init();
maps\_zombiemode_weap_thundergun::init();
maps\_zombiemode_weap_crossbow::init();
//Z2 TEMP DISABLE DURING INTEGRATION
maps\_zombiemode_bowie::bowie_init();
// maps\_zombiemode_betty::init();
// maps\_zombiemode_timer::init();
// maps\_zombiemode_auto_turret::init();
//maps\_zombiemode_protips::pro_tips_initialize();
maps\_zombiemode_traps::init();
maps\_zombiemode_weapon_box::init();
/#
maps\_zombiemode_devgui::init();
#/

init_function_overrides();

// ww: init the pistols in the game so last stand has the importance order
level thread last_stand_pistol_rank_init();

//thread maps\_zombiemode_rank::init();

// These MUST be threaded because they contain waits
//level thread maps\_zombiemode_deathcard::init();
//level thread maps\_zombiemode_money::init();
level thread [[level.Player_Spawn_func]]();
level thread onPlayerConnect();
level thread post_all_players_connected();

init_utility();
maps\_utility::registerClientSys("zombify"); // register a client system...
init_anims(); // zombie ai and anim inits

if( isDefined( level.custom_ai_type ) )
{
for( i = 0; i {
[[ level.custom_ai_type[i] ]]();
}
}

if( level.mutators[ "mutator_friendlyFire" ] )
{
SetDvar( "friendlyfire_enabled", "1" );
}

initZombieLeaderboardData();

// Fog in splitscreen
if( IsSplitScreen() )
{
set_splitscreen_fog( 350, 2986.33, 10000, -480, 0.805, 0.715, 0.61, 0.0, 10000 );
}
}

post_all_players_connected()
{
flag_wait( "all_players_connected" );
/#
execdevgui( "devgui_zombie" );
#/
println( "sessions: mapname=", level.script, " gametype zom isserver 1 player_count=", get_players().size );


maps\_zombiemode_score::init();
level difficulty_init();

//thread zombie_difficulty_ramp_up();

// DCS 091610: clear up blood patches when set to mature.
level thread clear_mature_blood();

// Start the Zombie MODE!
level thread end_game();
level thread round_start();
level thread players_playing();
if ( IsDefined( level.crawlers_enabled ) && level.crawlers_enabled == 1 )
{
level thread crawler_round_tracker();
}

//chrisp - adding spawning vo
//level thread spawn_vo();

//add ammo tracker for VO
level thread track_players_ammo_count();

//level thread prevent_near_origin();

DisableGrenadeSuicide();

level.startInvulnerableTime = GetDvarInt( #"player_deathInvulnerableTime" );
// level.global_damage_func = maps\_zombiemode_spawner::zombie_damage;
// level.global_damage_func_ads = maps\_zombiemode_spawner::zombie_damage_ads;

// TESTING
// wait( 3 );
// level thread intermission();
// thread testing_spawner_bug();

if(!IsDefined(level.music_override) )
{
level.music_override = false;
}
}

zombiemode_melee_miss()
{
if( isDefined( self.enemy.curr_pay_turret ) )
{
self.enemy doDamage( GetDvarInt( #"ai_meleeDamage" ), self.origin, self, undefined, "melee", "none" );
}
}

/*------------------------------------
chrisp - adding vo to track players ammo
------------------------------------*/
track_players_ammo_count()
{
self endon("disconnect");
self endon("death");

wait(5);

while(1)
{
players = get_players();
for(i=0;i {
if(!IsDefined (players[i].player_ammo_low))
{
players[i].player_ammo_low = 0;
}
if(!IsDefined(players[i].player_ammo_out))
{
players[i].player_ammo_out = 0;
}

weap = players[i] getcurrentweapon();
//iprintln("current weapon: " + weap);
//iprintlnbold(weap);
//Excludes all Perk based 'weapons' so that you don't get low ammo spam.
if(!isDefined(weap) || weap == "none" || weap == "zombie_perk_bottle_doubletap" || weap == "zombie_perk_bottle_jugg" || weap == "zombie_perk_bottle_revive" || weap == "zombie_perk_bottle_sleight" || weap == "mine_bouncing_betty" || weap == "claymore_zm" || weap == "syrette_sp" || weap == "zombie_knuckle_crack" || weap == "zombie_bowie_flourish" || issubstr( weap, "knife_ballistic_" ) || ( GetSubStr( weap, 0, 3) == "gl_" ) )
{
continue;
}
//iprintln("checking ammo for " + weap);
if ( players[i] GetAmmoCount( weap ) > 5)
{
continue;
}
if ( players[i] maps\_laststand::player_is_in_laststand() )
{
continue;
}
else if (players[i] GetAmmoCount( weap ) 0)
{
if (players[i].player_ammo_low != 1 )
{
players[i].player_ammo_low = 1;
players[i] maps\_zombiemode_audio::create_and_play_dialog( "general", "ammo_low" );
players[i] thread ammo_dialog_timer();
}

}
else if (players[i] GetAmmoCount( weap ) == 0)
{
if(!isDefined(weap) || weap == "none")
{
continue;
}
wait(2);
if( players[i].player_ammo_out != 1 )
{
players[i].player_ammo_out = 1;
players[i] maps\_zombiemode_audio::create_and_play_dialog( "general", "ammo_out" );
players[i] thread ammoout_dialog_timer();
}
}
else
{
continue;
}
}
wait(.5);
}
}
ammo_dialog_timer()
{
wait(20);
self.player_ammo_low = 0;
}
ammoout_dialog_timer()
{
wait(20);
self.player_ammo_out = 0;
}

/*------------------------------------
audio plays when more than 1 player connects
------------------------------------*/
spawn_vo()
{
//not sure if we need this
wait(1);

players = getplayers();

//just pick a random player for now and play some vo
if(players.size > 1)
{
player = random(players);
index = maps\_zombiemode_weapons::get_player_index(player);
player thread spawn_vo_player(index,players.size);
}

}

spawn_vo_player(index,num)
{
sound = "plr_" + index + "_vox_" + num +"play";
self playsound(sound, "sound_done");
self waittill("sound_done");
}

testing_spawner_bug()
{
wait( 0.1 );
level.round_number = 7;

spawners = [];
spawners[0] = GetEnt( "testy", "targetname" );
while( 1 )
{
wait( 1 );
level.enemy_spawns = spawners;
}
}

precache_shaders()
{
PrecacheShader( "hud_chalk_1" );
PrecacheShader( "hud_chalk_2" );
PrecacheShader( "hud_chalk_3" );
PrecacheShader( "hud_chalk_4" );
PrecacheShader( "hud_chalk_5" );

PrecacheShader( "zom_icon_community_pot" );
PrecacheShader( "zom_icon_community_pot_strip" );

precacheshader("zom_icon_player_life");
}

precache_models()
{
precachemodel( "char_ger_zombieeye" );
precachemodel( "p_zom_win_bars_01_vert04_bend_180" );
precachemodel( "p_zom_win_bars_01_vert01_bend_180" );
precachemodel( "p_zom_win_bars_01_vert04_bend" );
precachemodel( "p_zom_win_bars_01_vert01_bend" );
PreCacheModel( "p_zom_win_cell_bars_01_vert04_bent" );
precachemodel( "p_zom_win_cell_bars_01_vert01_bent" );
PrecacheModel( "tag_origin" );

// Counter models
PrecacheModel( "p_zom_counter_0" );
PrecacheModel( "p_zom_counter_1" );
PrecacheModel( "p_zom_counter_2" );
PrecacheModel( "p_zom_counter_3" );
PrecacheModel( "p_zom_counter_4" );
PrecacheModel( "p_zom_counter_5" );
PrecacheModel( "p_zom_counter_6" );
PrecacheModel( "p_zom_counter_7" );
PrecacheModel( "p_zom_counter_8" );
PrecacheModel( "p_zom_counter_9" );

// Player Tombstone
precachemodel("zombie_revive");

PrecacheModel( "zombie_z_money_icon" );
}

init_shellshocks()
{
level.player_killed_shellshock = "zombie_death";
PrecacheShellshock( level.player_killed_shellshock );
}

init_strings()
{
PrecacheString( &"ZOMBIE_WEAPONCOSTAMMO" );
PrecacheString( &"ZOMBIE_ROUND" );
PrecacheString( &"SCRIPT_PLUS" );
PrecacheString( &"ZOMBIE_GAME_OVER" );
PrecacheString( &"ZOMBIE_SURVIVED_ROUND" );
PrecacheString( &"ZOMBIE_SURVIVED_ROUNDS" );
PrecacheString( &"ZOMBIE_EXTRA_LIFE" );

add_zombie_hint( "undefined", &"ZOMBIE_UNDEFINED" );

// Random Treasure Chest
add_zombie_hint( "default_treasure_chest_950", &"ZOMBIE_RANDOM_WEAPON_950" );

// Barrier Pieces
add_zombie_hint( "default_buy_barrier_piece_10", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_10" );
add_zombie_hint( "default_buy_barrier_piece_20", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_20" );
add_zombie_hint( "default_buy_barrier_piece_50", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_50" );
add_zombie_hint( "default_buy_barrier_piece_100", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_100" );

// REWARD Barrier Pieces
add_zombie_hint( "default_reward_barrier_piece", &"ZOMBIE_BUTTON_REWARD_BARRIER" );
add_zombie_hint( "default_reward_barrier_piece_10", &"ZOMBIE_BUTTON_REWARD_BARRIER_10" );
add_zombie_hint( "default_reward_barrier_piece_20", &"ZOMBIE_BUTTON_REWARD_BARRIER_20" );
add_zombie_hint( "default_reward_barrier_piece_30", &"ZOMBIE_BUTTON_REWARD_BARRIER_30" );
add_zombie_hint( "default_reward_barrier_piece_40", &"ZOMBIE_BUTTON_REWARD_BARRIER_40" );
add_zombie_hint( "default_reward_barrier_piece_50", &"ZOMBIE_BUTTON_REWARD_BARRIER_50" );

// Debris
add_zombie_hint( "default_buy_debris_100", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_100" );
add_zombie_hint( "default_buy_debris_200", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_200" );
add_zombie_hint( "default_buy_debris_250", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_250" );
add_zombie_hint( "default_buy_debris_500", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_500" );
add_zombie_hint( "default_buy_debris_750", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_750" );
add_zombie_hint( "default_buy_debris_1000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1000" );
add_zombie_hint( "default_buy_debris_1250", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1250" );
add_zombie_hint( "default_buy_debris_1500", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1500" );
add_zombie_hint( "default_buy_debris_1750", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1750" );
add_zombie_hint( "default_buy_debris_2000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_2000" );

// Doors
add_zombie_hint( "default_buy_door_100", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_100" );
add_zombie_hint( "default_buy_door_200", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_200" );
add_zombie_hint( "default_buy_door_250", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_250" );
add_zombie_hint( "default_buy_door_500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_500" );
add_zombie_hint( "default_buy_door_750", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_750" );
add_zombie_hint( "default_buy_door_1000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1000" );
add_zombie_hint( "default_buy_door_1250", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1250" );
add_zombie_hint( "default_buy_door_1500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1500" );
add_zombie_hint( "default_buy_door_1750", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1750" );
add_zombie_hint( "default_buy_door_2000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_2000" );

// Areas
add_zombie_hint( "default_buy_area_100", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_100" );
add_zombie_hint( "default_buy_area_200", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_200" );
add_zombie_hint( "default_buy_area_250", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_250" );
add_zombie_hint( "default_buy_area_500", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_500" );
add_zombie_hint( "default_buy_area_750", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_750" );
add_zombie_hint( "default_buy_area_1000", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1000" );
add_zombie_hint( "default_buy_area_1250", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1250" );
add_zombie_hint( "default_buy_area_1500", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1500" );
add_zombie_hint( "default_buy_area_1750", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1750" );
add_zombie_hint( "default_buy_area_2000", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_2000" );

// POWER UPS
add_zombie_hint( "powerup_fire_sale_cost", &"ZOMBIE_FIRE_SALE_COST" );

}

init_sounds()
{
add_sound( "end_of_round", "mus_zmb_round_over" );
add_sound( "end_of_game", "mus_zmb_game_over" ); //Had to remove this and add a music state switch so that we can add other musical elements.
add_sound( "chalk_one_up", "mus_zmb_chalk" );
add_sound( "purchase", "zmb_cha_ching" );
add_sound( "no_purchase", "zmb_no_cha_ching" );

// Zombification
// TODO need to vary these up
add_sound( "playerzombie_usebutton_sound", "zmb_zombie_vocals_attack" );
add_sound( "playerzombie_attackbutton_sound", "zmb_zombie_vocals_attack" );
add_sound( "playerzombie_adsbutton_sound", "zmb_zombie_vocals_attack" );

// Head gib
add_sound( "zombie_head_gib", "zmb_zombie_head_gib" );

// Blockers
add_sound( "rebuild_barrier_piece", "zmb_repair_boards" );
add_sound( "rebuild_barrier_metal_piece", "zmb_metal_repair" );
add_sound( "rebuild_barrier_hover", "zmb_boards_float" );
add_sound( "debris_hover_loop", "zmb_couch_loop" );
add_sound( "break_barrier_piece", "zmb_break_boards" );
add_sound( "grab_metal_bar", "zmb_bar_pull" );
add_sound( "break_metal_bar", "zmb_bar_break" );
add_sound( "drop_metal_bar", "zmb_bar_drop" );
add_sound("blocker_end_move", "zmb_board_slam");
add_sound( "barrier_rebuild_slam", "zmb_board_slam" );
add_sound( "bar_rebuild_slam", "zmb_bar_repair" );

// Doors
add_sound( "door_slide_open", "zmb_door_slide_open" );
add_sound( "door_rotate_open", "zmb_door_slide_open" );

// Debris
add_sound( "debris_move", "zmb_weap_wall" );

// Random Weapon Chest
add_sound( "open_chest", "zmb_lid_open" );
add_sound( "music_chest", "zmb_music_box" );
add_sound( "close_chest", "zmb_lid_close" );

// Weapons on walls
add_sound( "weapon_show", "zmb_weap_wall" );

}

init_levelvars()
{
// Variables
// used to a check in last stand for players to become zombies
level.is_zombie_level = true;
level.laststandpistol = "m1911_zm"; // so we dont get the uber colt when we're knocked out
level.first_round = true;
level.round_number = 1;
level.round_start_time = 0;
level.pro_tips_start_time = 0;
level.intermission = false;
level.dog_intermission = false;
level.zombie_total = 0;
level.total_zombies_killed = 0;
level.no_laststandmissionfail = true;
level.hudelem_count = 0;
level.zombie_move_speed = 1;
level.enemy_spawns = []; // List of normal zombie spawners
level.zombie_rise_spawners = []; // List of zombie riser locations
// level.crawlers_enabled = 1;

// Used for kill counters
level.counter_model[0] = "p_zom_counter_0";
level.counter_model[1] = "p_zom_counter_1";
level.counter_model[2] = "p_zom_counter_2";
level.counter_model[3] = "p_zom_counter_3";
level.counter_model[4] = "p_zom_counter_4";
level.counter_model[5] = "p_zom_counter_5";
level.counter_model[6] = "p_zom_counter_6";
level.counter_model[7] = "p_zom_counter_7";
level.counter_model[8] = "p_zom_counter_8";
level.counter_model[9] = "p_zom_counter_9";

level.zombie_vars = [];

difficulty = 1;
column = int(difficulty) + 1;

//#######################################################################
// NOTE: These values are in mp/zombiemode.csv and will override
// whatever you put in as a value below. However, if they don't exist
// in the file, then the values below will be used.
//#######################################################################
// set_zombie_var( identifier, value, float, column );

// AI
set_zombie_var( "zombie_health_increase", 100, false, column ); // cumulatively add this to the zombies' starting health each round (up to round 10)
set_zombie_var( "zombie_health_increase_multiplier",0.1, true, column ); // after round 10 multiply the zombies' starting health by this amount
set_zombie_var( "zombie_health_start", 150, false, column ); // starting health of a zombie at round 1
set_zombie_var( "zombie_spawn_delay", 2.0, true, column ); // Base time to wait between spawning zombies. This is modified based on the round number.
set_zombie_var( "zombie_new_runner_interval", 10, false, column ); // Interval between changing walkers who are too far away into runners
set_zombie_var( "zombie_move_speed_multiplier", 8, false, column ); // Multiply by the round number to give the base speed value. 0-40 = walk, 41-70 = run, 71+ = sprint

set_zombie_var( "zombie_max_ai", 24, false, column ); // Base number of zombies per player (modified by round #)
set_zombie_var( "zombie_ai_per_player", 6, false, column ); // additional zombie modifier for each player in the game
set_zombie_var( "below_world_check", -1000 ); // Check height to see if a zombie has fallen through the world.

// Round
set_zombie_var( "spectators_respawn", true ); // Respawn in the spectators in between rounds
set_zombie_var( "zombie_use_failsafe", true ); // Will slowly kill zombies who are stuck
set_zombie_var( "zombie_between_round_time", 10 ); // How long to pause after the round ends
set_zombie_var( "zombie_intermission_time", 15 ); // Length of time to show the end of game stats
set_zombie_var( "game_start_delay", 0, false, column ); // How much time to give people a break before starting spawning

// Life and death
set_zombie_var( "penalty_no_revive", 0.10, true, column ); // Percentage of money you lose if you let a teammate die
set_zombie_var( "penalty_died", 0.0, true, column ); // Percentage of money lost if you die
set_zombie_var( "penalty_downed", 0.05, true, column ); // Percentage of money lost if you go down // ww: told to remove downed point loss
set_zombie_var( "starting_lives", 1, false, column ); // How many lives a solo player starts out with

players = get_players();
points = set_zombie_var( ("zombie_score_start_"+players.size+"p"), 3000, false, column );
points = set_zombie_var( ("zombie_score_start_"+players.size+"p"), 3000, false, column );


set_zombie_var( "zombie_score_kill_4player", 50 ); // Individual Points for a zombie kill in a 4 player game
set_zombie_var( "zombie_score_kill_3player", 50 ); // Individual Points for a zombie kill in a 3 player game
set_zombie_var( "zombie_score_kill_2player", 50 ); // Individual Points for a zombie kill in a 2 player game
set_zombie_var( "zombie_score_kill_1player", 50 ); // Individual Points for a zombie kill in a 1 player game

set_zombie_var( "zombie_score_kill_4p_team", 30 ); // Team Points for a zombie kill in a 4 player game
set_zombie_var( "zombie_score_kill_3p_team", 35 ); // Team Points for a zombie kill in a 3 player game
set_zombie_var( "zombie_score_kill_2p_team", 45 ); // Team Points for a zombie kill in a 2 player game
set_zombie_var( "zombie_score_kill_1p_team", 0 ); // Team Points for a zombie kill in a 1 player game

set_zombie_var( "zombie_score_damage_normal", 10 ); // points gained for a hit with a non-automatic weapon
set_zombie_var( "zombie_score_damage_light", 10 ); // points gained for a hit with an automatic weapon

set_zombie_var( "zombie_score_bonus_melee", 80 ); // Bonus points for a melee kill
set_zombie_var( "zombie_score_bonus_head", 50 ); // Bonus points for a head shot kill
set_zombie_var( "zombie_score_bonus_neck", 20 ); // Bonus points for a neck shot kill
set_zombie_var( "zombie_score_bonus_torso", 10 ); // Bonus points for a torso shot kill
set_zombie_var( "zombie_score_bonus_burn", 10 ); // Bonus points for a burn kill

set_zombie_var( "zombie_flame_dmg_point_delay", 500 );

set_zombie_var( "zombify_player", false ); // Default to not zombify the player till further support

if ( IsSplitScreen() )
{
set_zombie_var( "zombie_timer_offset", 280 ); // hud offsets
}
}

init_dvars()
{
setSavedDvar( "fire_world_damage", "0" );
setSavedDvar( "fire_world_damage_rate", "0" );
setSavedDvar( "fire_world_damage_duration", "0" );

if( GetDvar( #"zombie_debug" ) == "" )
{
SetDvar( "zombie_debug", "0" );
}

if( GetDvar( #"zombie_cheat" ) == "" )
{
SetDvar( "zombie_cheat", "0" );
}

if(GetDvar( #"magic_chest_movable") == "")
{
SetDvar( "magic_chest_movable", "1" );
}

if(GetDvar( #"magic_box_explore_only") == "")
{
SetDvar( "magic_box_explore_only", "1" );
}

SetDvar( "revive_trigger_radius", "75" );
SetDvar( "player_lastStandBleedoutTime", "45" );

SetDvar( "scr_deleteexplosivesonspawn", "0" );

// HACK: To avoid IK crash in zombiemode: MikeA 9/18/2009
//setDvar( "ik_enable", "0" );
}


init_mutators()
{
level.mutators = [];

init_mutator( "mutator_noPerks" );
init_mutator( "mutator_noTraps" );
init_mutator( "mutator_noMagicBox" );
init_mutator( "mutator_noRevive" );
init_mutator( "mutator_noPowerups" );
init_mutator( "mutator_noReloads" );
init_mutator( "mutator_noBoards" );
init_mutator( "mutator_fogMatch" );
init_mutator( "mutator_quickStart" );
init_mutator( "mutator_headshotsOnly" );
init_mutator( "mutator_friendlyFire" );
init_mutator( "mutator_doubleMoney" );
init_mutator( "mutator_susceptible" );
init_mutator( "mutator_powerShot" );
}

init_mutator( mutator_s )
{
level.mutators[ mutator_s ] = ( "1" == GetDvar( mutator_s ) );
}


init_function_overrides()
{
// Function pointers
level.custom_introscreen = ::zombie_intro_screen;
level.custom_intermission = ::player_intermission;
level.reset_clientdvars = ::onPlayerConnect_clientDvars;
// Sets up function pointers for animscripts to refer to
level.playerlaststand_func = ::player_laststand;
// level.global_kill_func = maps\_zombiemode_spawner::zombie_death;
level.global_damage_func = maps\_zombiemode_spawner::zombie_damage;
level.global_damage_func_ads = maps\_zombiemode_spawner::zombie_damage_ads;
level.overridePlayerKilled = ::player_killed_override;
level.overridePlayerDamage = ::player_damage_override;
level.overrideActorKilled = ::actor_killed_override;
level.overrideActorDamage = ::actor_damage_override;
level.melee_miss_func = ::zombiemode_melee_miss;
level.player_becomes_zombie = ::zombify_player;
level.is_friendly_fire_on = ::is_friendly_fire_on;
level.can_revive = ::can_revive;
level.zombie_last_stand = ::last_stand_pistol_swap;
level.zombie_last_stand_pistol_memory = ::last_stand_save_pistol_ammo;
level.zombie_last_stand_ammo_return = ::last_stand_restore_pistol_ammo;

if( !IsDefined( level.Player_Spawn_func ) )
{
level.Player_Spawn_func = ::coop_player_spawn_placement;
}
}


// for zombietron, see maps\_zombietron_main::initZombieLeaderboardData()
//
initZombieLeaderboardData()
{
// Initializing Leaderboard Stat Variables -- string values match stats.ddl
level.zombieLeaderboardStatVariable["zombie_theater"]["highestwave"] = "zombie_theater_highestwave";
level.zombieLeaderboardStatVariable["zombie_theater"]["timeinwave"] = "zombie_theater_timeinwave";
level.zombieLeaderboardStatVariable["zombie_theater"]["totalpoints"] = "zombie_theater_totalpoints";

level.zombieLeaderboardStatVariable["zombie_pentagon"]["highestwave"] = "zombie_pentagon_highestwave";
level.zombieLeaderboardStatVariable["zombie_pentagon"]["timeinwave"] = "zombie_pentagon_timeinwave";
level.zombieLeaderboardStatVariable["zombie_pentagon"]["totalpoints"] = "zombie_pentagon_totalpoints";

// Initializing Leaderboard Number. Matches values in live_leaderboard.h.
level.zombieLeaderboardNumber["zombie_theater"]["waves"] = 0;
level.zombieLeaderboardNumber["zombie_theater"]["points"] = 1;

// level.zombieLeaderboardNumber["zombietron"]["waves"] = 3; // defined in _zombietron_main.gsc
// level.zombieLeaderboardNumber["zombietron"]["points"] = 4; // defined in _zombietron_main.gsc

level.zombieLeaderboardNumber["zombie_pentagon"]["waves"] = 6;
level.zombieLeaderboardNumber["zombie_pentagon"]["points"] = 7;
}


init_flags()
{
flag_init( "spawn_point_override" );
flag_init( "power_on" );
flag_init( "crawler_round" );
flag_init( "spawn_zombies", true );
flag_init( "dog_round" );
flag_init( "begin_spawning" );
flag_init( "end_round_wait" );
flag_init( "wait_and_revive" );
}

// Client flags registered here should be for global zombie systems, and should
// prefer to use high flag numbers and work downwards.

// Level specific flags should be registered in the level, and should prefer
// low numbers, and work upwards.

// Ensure that this function and the function in _zombiemode.csc match.

init_client_flags()
{
// Client flags for script movers

level._ZOMBIE_SCRIPTMOVER_FLAG_BOX_RANDOM = 15;

// Client flags for the player

level._ZOMBIE_PLAYER_FLAG_CLOAK_WEAPON = 14;

// Client flags for actors
}

init_fx()
{
level._effect["wood_chunk_destory"] = LoadFX( "impacts/fx_large_woodhit" );
level._effect["fx_zombie_bar_break"] = LoadFX( "maps/zombie/fx_zombie_bar_break" );
level._effect["fx_zombie_bar_break_lite"] = LoadFX( "maps/zombie/fx_zombie_bar_break_lite" );

level._effect["edge_fog"] = LoadFX( "maps/zombie/fx_fog_zombie_amb" );
level._effect["chest_light"] = LoadFX( "env/light/fx_ray_sun_sm_short" );

level._effect["eye_glow"] = LoadFX( "misc/fx_zombie_eye_single" );

level._effect["headshot"] = LoadFX( "impacts/fx_flesh_hit" );
level._effect["headshot_nochunks"] = LoadFX( "misc/fx_zombie_bloodsplat" );
level._effect["bloodspurt"] = LoadFX( "misc/fx_zombie_bloodspurt" );
level._effect["tesla_head_light"] = LoadFX( "maps/zombie/fx_zombie_tesla_neck_spurt");

level._effect["rise_burst_water"] = LoadFX("maps/zombie/fx_zombie_body_wtr_burst");
level._effect["rise_billow_water"] = LoadFX("maps/zombie/fx_zombie_body_wtr_billowing");
level._effect["rise_dust_water"] = LoadFX("maps/zombie/fx_zombie_body_wtr_falling");

level._effect["rise_burst"] = LoadFX("maps/zombie/fx_mp_zombie_hand_dirt_burst");
level._effect["rise_billow"] = LoadFX("maps/zombie/fx_mp_zombie_body_dirt_billowing");
level._effect["rise_dust"] = LoadFX("maps/zombie/fx_mp_zombie_body_dust_falling");

// Flamethrower
level._effect["character_fire_pain_sm"] = LoadFX( "env/fire/fx_fire_player_sm_1sec" );
level._effect["character_fire_death_sm"] = LoadFX( "env/fire/fx_fire_player_md" );
level._effect["character_fire_death_torso"] = LoadFX( "env/fire/fx_fire_player_torso" );

level._effect["def_explosion"] = LoadFX("explosions/fx_default_explosion");
level._effect["betty_explode"] = LoadFX("weapon/bouncing_betty/fx_explosion_betty_generic");
}


// zombie specific anims
init_standard_zombie_anims()
{
// deaths
level.scr_anim["zombie"]["death1"] = %ai_zombie_death_v1;
level.scr_anim["zombie"]["death2"] = %ai_zombie_death_v2;
level.scr_anim["zombie"]["death3"] = %ai_zombie_crawl_death_v1;
level.scr_anim["zombie"]["death4"] = %ai_zombie_crawl_death_v2;

// run cycles

level.scr_anim["zombie"]["walk1"] = %ai_zombie_walk_v1;
level.scr_anim["zombie"]["walk2"] = %ai_zombie_walk_v2;
level.scr_anim["zombie"]["walk3"] = %ai_zombie_walk_v3;
level.scr_anim["zombie"]["walk4"] = %ai_zombie_walk_v4;
level.scr_anim["zombie"]["walk5"] = %ai_zombie_walk_v6;
level.scr_anim["zombie"]["walk6"] = %ai_zombie_walk_v7;
level.scr_anim["zombie"]["walk7"] = %ai_zombie_walk_v9; //was goose step walk - overridden in theatre only (v8)
level.scr_anim["zombie"]["walk8"] = %ai_zombie_walk_v9;

level.scr_anim["zombie"]["run1"] = %ai_zombie_walk_fast_v1;
level.scr_anim["zombie"]["run2"] = %ai_zombie_walk_fast_v2;
level.scr_anim["zombie"]["run3"] = %ai_zombie_walk_fast_v3;
level.scr_anim["zombie"]["run4"] = %ai_zombie_run_v2;
level.scr_anim["zombie"]["run5"] = %ai_zombie_run_v4;
level.scr_anim["zombie"]["run6"] = %ai_zombie_run_v3;
//level.scr_anim["zombie"]["run4"] = %ai_zombie_run_v1;
//level.scr_anim["zombie"]["run6"] = %ai_zombie_run_v4;

level.scr_anim["zombie"]["sprint1"] = %ai_zombie_sprint_v1;
level.scr_anim["zombie"]["sprint2"] = %ai_zombie_sprint_v2;
level.scr_anim["zombie"]["sprint3"] = %ai_zombie_sprint_v1;
level.scr_anim["zombie"]["sprint4"] = %ai_zombie_sprint_v2;
//level.scr_anim["zombie"]["sprint3"] = %ai_zombie_sprint_v3;
//level.scr_anim["zombie"]["sprint3"] = %ai_zombie_sprint_v4;
//level.scr_anim["zombie"]["sprint4"] = %ai_zombie_sprint_v5;

// run cycles in prone
level.scr_anim["zombie"]["crawl1"] = %ai_zombie_crawl;
level.scr_anim["zombie"]["crawl2"] = %ai_zombie_crawl_v1;
level.scr_anim["zombie"]["crawl3"] = %ai_zombie_crawl_v2;
level.scr_anim["zombie"]["crawl4"] = %ai_zombie_crawl_v3;
level.scr_anim["zombie"]["crawl5"] = %ai_zombie_crawl_v4;
level.scr_anim["zombie"]["crawl6"] = %ai_zombie_crawl_v5;
level.scr_anim["zombie"]["crawl_hand_1"] = %ai_zombie_walk_on_hands_a;
level.scr_anim["zombie"]["crawl_hand_2"] = %ai_zombie_walk_on_hands_b;

level.scr_anim["zombie"]["crawl_sprint1"] = %ai_zombie_crawl_sprint;
level.scr_anim["zombie"]["crawl_sprint2"] = %ai_zombie_crawl_sprint_1;
level.scr_anim["zombie"]["crawl_sprint3"] = %ai_zombie_crawl_sprint_2;

if( !isDefined( level._zombie_melee ) )
{
level._zombie_melee = [];
}
if( !isDefined( level._zombie_walk_melee ) )
{
level._zombie_walk_melee = [];
}
if( !isDefined( level._zombie_run_melee ) )
{
level._zombie_run_melee = [];
}

level._zombie_melee["zombie"] = [];
level._zombie_walk_melee["zombie"] = [];
level._zombie_run_melee["zombie"] = [];


level._zombie_melee["zombie"][0] = %ai_zombie_attack_v2; // slow swipes
level._zombie_melee["zombie"][1] = %ai_zombie_attack_v4; // single left swipe
level._zombie_melee["zombie"][2] = %ai_zombie_attack_v6; // wierd single
level._zombie_melee["zombie"][3] = %ai_zombie_attack_v1; // DOUBLE SWIPE
level._zombie_melee["zombie"][4] = %ai_zombie_attack_forward_v1; // DOUBLE SWIPE
level._zombie_melee["zombie"][5] = %ai_zombie_attack_forward_v2; // slow DOUBLE SWIPE

level._zombie_run_melee["zombie"][0] = %ai_zombie_run_attack_v1; // fast single right
level._zombie_run_melee["zombie"][1] = %ai_zombie_run_attack_v2; // fast double swipe
level._zombie_run_melee["zombie"][2] = %ai_zombie_run_attack_v3; // fast swipe

if( isDefined( level.zombie_anim_override ) )
{
[[ level.zombie_anim_override ]]();
}

// melee in walk
level._zombie_walk_melee["zombie"][0] = %ai_zombie_walk_attack_v1; // fast single right swipe
level._zombie_walk_melee["zombie"][1] = %ai_zombie_walk_attack_v2; // slow right/left single hit
level._zombie_walk_melee["zombie"][2] = %ai_zombie_walk_attack_v3; // fast single left swipe
level._zombie_walk_melee["zombie"][3] = %ai_zombie_walk_attack_v4; // slow single right swipe

// melee in crawl
if( !isDefined( level._zombie_melee_crawl ) )
{
level._zombie_melee_crawl = [];
}
level._zombie_melee_crawl["zombie"] = [];
level._zombie_melee_crawl["zombie"][0] = %ai_zombie_attack_crawl;
level._zombie_melee_crawl["zombie"][1] = %ai_zombie_attack_crawl_lunge;

if( !isDefined( level._zombie_stumpy_melee ) )
{
level._zombie_stumpy_melee = [];
}
level._zombie_stumpy_melee["zombie"] = [];
level._zombie_stumpy_melee["zombie"][0] = %ai_zombie_walk_on_hands_shot_a;
level._zombie_stumpy_melee["zombie"][1] = %ai_zombie_walk_on_hands_shot_b;
//level._zombie_melee_crawl["zombie"][2] = %ai_zombie_crawl_attack_A;

// tesla deaths
if( !isDefined( level._zombie_tesla_death ) )
{
level._zombie_tesla_death = [];
}
level._zombie_tesla_death["zombie"] = [];
level._zombie_tesla_death["zombie"][0] = %ai_zombie_tesla_death_a;
level._zombie_tesla_death["zombie"][1] = %ai_zombie_tesla_death_b;
level._zombie_tesla_death["zombie"][2] = %ai_zombie_tesla_death_c;
level._zombie_tesla_death["zombie"][3] = %ai_zombie_tesla_death_d;
level._zombie_tesla_death["zombie"][4] = %ai_zombie_tesla_death_e;

if( !isDefined( level._zombie_tesla_crawl_death ) )
{
level._zombie_tesla_crawl_death = [];
}
level._zombie_tesla_crawl_death["zombie"] = [];
level._zombie_tesla_crawl_death["zombie"][0] = %ai_zombie_tesla_crawl_death_a;
level._zombie_tesla_crawl_death["zombie"][1] = %ai_zombie_tesla_crawl_death_b;

// thundergun knockdowns and getups
if( !isDefined( level._zombie_knockdowns ) )
{
level._zombie_knockdowns = [];
}
level._zombie_knockdowns["zombie"] = [];
level._zombie_knockdowns["zombie"]["front"] = [];

level._zombie_knockdowns["zombie"]["front"]["no_legs"] = [];
level._zombie_knockdowns["zombie"]["front"]["no_legs"][0] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["no_legs"][1] = %ai_zombie_thundergun_hit_doublebounce;
level._zombie_knockdowns["zombie"]["front"]["no_legs"][2] = %ai_zombie_thundergun_hit_forwardtoface;

level._zombie_knockdowns["zombie"]["front"]["has_legs"] = [];

level._zombie_knockdowns["zombie"]["front"]["has_legs"][0] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][1] = %ai_zombie_thundergun_hit_doublebounce;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][2] = %ai_zombie_thundergun_hit_upontoback;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][3] = %ai_zombie_thundergun_hit_forwardtoface;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][4] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][5] = %ai_zombie_thundergun_hit_forwardtoface;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][6] = %ai_zombie_thundergun_hit_stumblefall;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][7] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][8] = %ai_zombie_thundergun_hit_doublebounce;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][9] = %ai_zombie_thundergun_hit_upontoback;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][10] = %ai_zombie_thundergun_hit_forwardtoface;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][11] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][12] = %ai_zombie_thundergun_hit_forwardtoface;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][13] = %ai_zombie_thundergun_hit_deadfallknee;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][14] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][15] = %ai_zombie_thundergun_hit_doublebounce;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][16] = %ai_zombie_thundergun_hit_upontoback;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][17] = %ai_zombie_thundergun_hit_forwardtoface;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][18] = %ai_zombie_thundergun_hit_armslegsforward;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][19] = %ai_zombie_thundergun_hit_forwardtoface;
level._zombie_knockdowns["zombie"]["front"]["has_legs"][20] = %ai_zombie_thundergun_hit_flatonback;

level._zombie_knockdowns["zombie"]["left"] = [];
level._zombie_knockdowns["zombie"]["left"][0] = %ai_zombie_thundergun_hit_legsout_right;

level._zombie_knockdowns["zombie"]["right"] = [];
level._zombie_knockdowns["zombie"]["right"][0] = %ai_zombie_thundergun_hit_legsout_left;

level._zombie_knockdowns["zombie"]["back"] = [];
level._zombie_knockdowns["zombie"]["back"][0] = %ai_zombie_thundergun_hit_faceplant;

if( !isDefined( level._zombie_getups ) )
{
level._zombie_getups = [];
}
level._zombie_getups["zombie"] = [];
level._zombie_getups["zombie"]["back"] = [];

level._zombie_getups["zombie"]["back"]["early"] = [];
level._zombie_getups["zombie"]["back"]["early"][0] = %ai_zombie_thundergun_getup_b;
level._zombie_getups["zombie"]["back"]["early"][1] = %ai_zombie_thundergun_getup_c;

level._zombie_getups["zombie"]["back"]["late"] = [];
level._zombie_getups["zombie"]["back"]["late"][0] = %ai_zombie_thundergun_getup_b;
level._zombie_getups["zombie"]["back"]["late"][1] = %ai_zombie_thundergun_getup_c;
level._zombie_getups["zombie"]["back"]["late"][2] = %ai_zombie_thundergun_getup_quick_b;
level._zombie_getups["zombie"]["back"]["late"][3] = %ai_zombie_thundergun_getup_quick_c;

level._zombie_getups["zombie"]["belly"] = [];

level._zombie_getups["zombie"]["belly"]["early"] = [];
level._zombie_getups["zombie"]["belly"]["early"][0] = %ai_zombie_thundergun_getup_a;

level._zombie_getups["zombie"]["belly"]["late"] = [];
level._zombie_getups["zombie"]["belly"]["late"][0] = %ai_zombie_thundergun_getup_a;
level._zombie_getups["zombie"]["belly"]["late"][1] = %ai_zombie_thundergun_getup_quick_a;

// freezegun deaths
if( !isDefined( level._zombie_freezegun_death ) )
{
level._zombie_freezegun_death = [];
}
level._zombie_freezegun_death["zombie"] = [];
level._zombie_freezegun_death["zombie"][0] = %ai_zombie_freeze_death_a;
level._zombie_freezegun_death["zombie"][1] = %ai_zombie_freeze_death_b;
level._zombie_freezegun_death["zombie"][2] = %ai_zombie_freeze_death_c;
level._zombie_freezegun_death["zombie"][3] = %ai_zombie_freeze_death_d;
level._zombie_freezegun_death["zombie"][4] = %ai_zombie_freeze_death_e;

if( !isDefined( level._zombie_freezegun_death_missing_legs ) )
{
level._zombie_freezegun_death_missing_legs = [];
}
level._zombie_freezegun_death_missing_legs["zombie"] = [];
level._zombie_freezegun_death_missing_legs["zombie"][0] = %ai_zombie_crawl_freeze_death_01;
level._zombie_freezegun_death_missing_legs["zombie"][1] = %ai_zombie_crawl_freeze_death_02;

// deaths
if( !isDefined( level._zombie_deaths ) )
{
level._zombie_deaths = [];
}
level._zombie_deaths["zombie"] = [];
level._zombie_deaths["zombie"][0] = %ch_dazed_a_death;
level._zombie_deaths["zombie"][1] = %ch_dazed_b_death;
level._zombie_deaths["zombie"][2] = %ch_dazed_c_death;
level._zombie_deaths["zombie"][3] = %ch_dazed_d_death;

/*
ground crawl
*/

if( !isDefined( level._zombie_rise_anims ) )
{
level._zombie_rise_anims = [];
}

// set up the arrays
level._zombie_rise_anims["zombie"] = [];

//level._zombie_rise_anims["zombie"][1]["walk"][0] = %ai_zombie_traverse_ground_v1_crawl;
level._zombie_rise_anims["zombie"][1]["walk"][0] = %ai_zombie_traverse_ground_v1_walk;

//level._zombie_rise_anims["zombie"][1]["run"][0] = %ai_zombie_traverse_ground_v1_crawlfast;
level._zombie_rise_anims["zombie"][1]["run"][0] = %ai_zombie_traverse_ground_v1_run;

level._zombie_rise_anims["zombie"][1]["sprint"][0] = %ai_zombie_traverse_ground_climbout_fast;

//level._zombie_rise_anims["zombie"][2]["walk"][0] = %ai_zombie_traverse_ground_v2_walk; //!broken
level._zombie_rise_anims["zombie"][2]["walk"][0] = %ai_zombie_traverse_ground_v2_walk_altA;
//level._zombie_rise_anims["zombie"][2]["walk"][2] = %ai_zombie_traverse_ground_v2_walk_altB;//!broken

// ground crawl death
if( !isDefined( level._zombie_rise_death_anims ) )
{
level._zombie_rise_death_anims = [];
}

level._zombie_rise_death_anims["zombie"] = [];

level._zombie_rise_death_anims["zombie"][1]["in"][0] = %ai_zombie_traverse_ground_v1_deathinside;
level._zombie_rise_death_anims["zombie"][1]["in"][1] = %ai_zombie_traverse_ground_v1_deathinside_alt;

level._zombie_rise_death_anims["zombie"][1]["out"][0] = %ai_zombie_traverse_ground_v1_deathoutside;
level._zombie_rise_death_anims["zombie"][1]["out"][1] = %ai_zombie_traverse_ground_v1_deathoutside_alt;

level._zombie_rise_death_anims["zombie"][2]["in"][0] = %ai_zombie_traverse_ground_v2_death_low;
level._zombie_rise_death_anims["zombie"][2]["in"][1] = %ai_zombie_traverse_ground_v2_death_low_alt;

level._zombie_rise_death_anims["zombie"][2]["out"][0] = %ai_zombie_traverse_ground_v2_death_high;
level._zombie_rise_death_anims["zombie"][2]["out"][1] = %ai_zombie_traverse_ground_v2_death_high_alt;

//taunts
if( !isDefined( level._zombie_run_taunt ) )
{
level._zombie_run_taunt = [];
}
if( !isDefined( level._zombie_board_taunt ) )
{
level._zombie_board_taunt = [];
}
level._zombie_run_taunt["zombie"] = [];
level._zombie_board_taunt["zombie"] = [];

//level._zombie_taunt["zombie"][0] = %ai_zombie_taunts_1;
//level._zombie_taunt["zombie"][1] = %ai_zombie_taunts_4;
//level._zombie_taunt["zombie"][2] = %ai_zombie_taunts_5b;
//level._zombie_taunt["zombie"][3] = %ai_zombie_taunts_5c;
//level._zombie_taunt["zombie"][4] = %ai_zombie_taunts_5d;
//level._zombie_taunt["zombie"][5] = %ai_zombie_taunts_5e;
//level._zombie_taunt["zombie"][6] = %ai_zombie_taunts_5f;
//level._zombie_taunt["zombie"][7] = %ai_zombie_taunts_7;
//level._zombie_taunt["zombie"][8] = %ai_zombie_taunts_9;
//level._zombie_taunt["zombie"][8] = %ai_zombie_taunts_11;
//level._zombie_taunt["zombie"][8] = %ai_zombie_taunts_12;

level._zombie_board_taunt["zombie"][0] = %ai_zombie_taunts_4;
level._zombie_board_taunt["zombie"][1] = %ai_zombie_taunts_7;
level._zombie_board_taunt["zombie"][2] = %ai_zombie_taunts_9;
level._zombie_board_taunt["zombie"][3] = %ai_zombie_taunts_5b;
level._zombie_board_taunt["zombie"][4] = %ai_zombie_taunts_5c;
level._zombie_board_taunt["zombie"][5] = %ai_zombie_taunts_5d;
level._zombie_board_taunt["zombie"][6] = %ai_zombie_taunts_5e;
level._zombie_board_taunt["zombie"][7] = %ai_zombie_taunts_5f;
}

init_anims()
{
init_standard_zombie_anims();
}

// Initialize any animscript related variables
init_animscripts()
{
// Setup the animscripts, then override them (we call this just incase an AI has not yet spawned)
animscripts\zombie_init::firstInit();

anim.idleAnimArray ["stand"] = [];
anim.idleAnimWeights ["stand"] = [];
anim.idleAnimArray ["stand"][0][0] = %ai_zombie_idle_v1_delta;
anim.idleAnimWeights ["stand"][0][0] = 10;

anim.idleAnimArray ["crouch"] = [];
anim.idleAnimWeights ["crouch"] = [];
anim.idleAnimArray ["crouch"][0][0] = %ai_zombie_idle_crawl_delta;
anim.idleAnimWeights ["crouch"][0][0] = 10;
}

// Handles the intro screen
zombie_intro_screen( string1, string2, string3, string4, string5 )
{
flag_wait( "all_players_connected" );
}

players_playing()
{
// initialize level.players_playing
players = get_players();
level.players_playing = players.size;

wait( 20 );

players = get_players();
level.players_playing = players.size;
}


// Init some additional settings based on difficulty and number of players
//
difficulty_init()
{
flag_wait( "all_players_connected" );

difficulty =1;
table = "mp/zombiemode.csv";
column = int(difficulty)+1;
players = get_players();
points = 500;


// Get individual starting points
points = set_zombie_var( ("zombie_score_start_"+players.size+"p"), 3000, false, column );
/#
if( GetDvarInt( #"zombie_cheat" ) >= 1 )
{
points = 100000;
}
#/
for ( p=0; p {
players[p].score = points;
players[p].score_total = players[p].score;
players[p].old_score = players[p].score;
}

// Get team starting points
points = set_zombie_var( ("zombie_team_score_start_"+players.size+"p"), 2000, false, column );
/#
if( GetDvarInt( #"zombie_cheat" ) >= 1 )
{
points = 100000;
}
#/
for ( tp = 0; tp {
pool = level.team_pool[ tp ];
pool.score = points;
pool.old_score = pool.score;
pool.score_total = pool.score;
}

// Other difficulty-specific changes
switch ( difficulty )
{
case "0":
case "1":
break;
case "2":
level.first_round = false;
level.round_number = 8;
break;
case "3":
level.first_round = false;
level.round_number = 18;
break;
default:
break;
}

if( level.mutators["mutator_quickStart"] )
{
level.first_round = false;
level.round_number = 5;
}
}


//
// NETWORK SECTION ====================================================================== //
//

watchTakenDamage()
{
self endon( "disconnect" );
self endon( "death" );

self.has_taken_damage = false;
while(1)
{
self waittill("damage", damage_amount );

if ( 0 {
self.has_taken_damage = true;
return;
}
}
}

onPlayerConnect()
{
for( ;; )
{
level waittill( "connecting", player );

player.entity_num = player GetEntityNumber();
player thread onPlayerSpawned();
player thread onPlayerDisconnect();
player thread player_revive_monitor();

player thread watchTakenDamage();

player.score = 0;
player.score_total = player.score;
player.old_score = player.score;

player.is_zombie = false;
player.initialized = false;
player.zombification_time = 0;
player.enableText = true;

player.team_num = 0;

player setTeamForEntity( "allies" );

//player maps\_zombiemode_protips::player_init();

// DCS 090910: now that player can destroy some barricades before set.
player thread maps\_zombiemode_blockers::rebuild_barrier_reward_reset();
}
}

onPlayerConnect_clientDvars()
{
self SetClientDvars( "cg_deadChatWithDead", "1",
"cg_deadChatWithTeam", "1",
"cg_deadHearTeamLiving", "1",
"cg_deadHearAllLiving", "1",
"cg_everyoneHearsEveryone", "1",
"compass", "0",
"hud_showStance", "0",
"cg_thirdPerson", "0",
"cg_fov", "65",
"cg_thirdPersonAngle", "0",
"ammoCounterHide", "1",
"miniscoreboardhide", "1",
"cg_drawSpectatorMessages", "0",
"ui_hud_hardcore", "0" );

self SetDepthOfField( 0, 0, 512, 4000, 4, 0 );

// Enabling the FPS counter in ship for now
//self setclientdvar( "cg_drawfps", "1" );

self setClientDvar( "aim_lockon_pitch_strength", 0.0 );

if(!level.wii)
{
// self SetClientDvar("r_enablePlayerShadow", 1);
}
}



checkForAllDead()
{
players = get_players();
count = 0;
for( i = 0; i {
if( !(players[i] maps\_laststand::player_is_in_laststand()) && !(players[i].sessionstate == "spectator") )
{
count++;
}
}

if( count==0 )
{
level notify( "end_game" );
}
}


onPlayerDisconnect()
{
self waittill( "disconnect" );
self remove_from_spectate_list();
self checkForAllDead();
}


//
// Runs when the player spawns into the map
// self is the player.surprise!
//
onPlayerSpawned()
{
self endon( "disconnect" );

for( ;; )
{
self waittill( "spawned_player" );

self enablehealthshield( false );
/#
if ( GetDvarInt( #"zombie_cheat" ) >= 1 && GetDvarInt( #"zombie_cheat" ) {
self EnableInvulnerability();
}
#/

self SetClientDvars( "cg_thirdPerson", "0",
"cg_fov", "65",
"cg_thirdPersonAngle", "0" );

self SetDepthOfField( 0, 0, 512, 4000, 4, 0 );

self cameraactivate(false);

self add_to_spectate_list();

if( isdefined( self.initialized ) )
{
if( self.initialized == false )
{
self.initialized = true;

// ww: set the is_drinking variable
self.is_drinking = 0;

// set the initial score on the hud
self maps\_zombiemode_score::set_player_score_hud( true );
self thread player_zombie_breadcrumb();

// This will keep checking to see if you're trying to use an ability.
//self thread maps\_zombiemode_ability::hardpointItemWaiter();

//self thread maps\_zombiemode_ability::hardPointItemSelector();

//Init stat tracking variables
self.stats["kills"] = 0;
self.stats["score"] = 0;
self.stats["downs"] = 0;
self.stats["revives"] = 0;
self.stats["perks"] = 0;
self.stats["headshots"] = 0;
self.stats["zombie_gibs"] = 0;
}
}
}
}


//
// Keep track of players going down and getting revived
player_revive_monitor()
{
self endon( "disconnect" );

while (1)
{
self waittill( "player_revived", reviver );

//AYERS: Working on Laststand Audio
//self clientnotify( "revived" );

bbPrint( "zombie_playerdeaths: round %d playername %s deathtype revived x %f y %f z %f", level.round_number, self.playername, self.origin );

//self laststand_giveback_player_perks();

if ( IsDefined(reviver) )
{
self maps\_zombiemode_audio::create_and_play_dialog( "general", "revive_up" );

//reviver maps\_zombiemode_rank::giveRankXp( "revive" );
//maps\_zombiemode_challenges::doMissionCallback( "zm_revive", reviver );

// Check to see how much money you lost from being down.
points = self.score_lost_when_downed;
reviver maps\_zombiemode_score::player_add_points( "reviver", points );
self.score_lost_when_downed = 0;
}
}
}


// self = a player
// If the player has just 1 perk, they wil always get it back
// If the player has more than 1 perk, they will lose a single perk
laststand_giveback_player_perks()
{
if ( IsDefined( self.laststand_perks ) )
{
// Calculate a lost perk index
lost_perk_index = int( -1 );
if( self.laststand_perks.size > 1 )
{
lost_perk_index = RandomInt( self.laststand_perks.size-1 );
}

// Give the player back their perks
for ( i=0; i {
if ( self HasPerk( self.laststand_perks[i] ) )
{
continue;
}
if( i == lost_perk_index )
{
continue;
}

maps\_zombiemode_perks::give_perk( self.laststand_perks[i] );
}
}
}

Link to comment

Part 2 of above...


remote_revive_watch()
{
self endon( "death" );
self endon( "player_revived" );

self waittill( "remote_revive", reviver );

self maps\_laststand::remote_revive( reviver );
}

player_laststand( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{
// Grab the perks, we'll give them back to the player if he's revived
//self.laststand_perks = maps\_zombiekmode_deathcard::deathcard_save_perks( self );

//AYERS: Working on Laststand Audio
/*
players = get_players();
if( players.size >= 2 )
{
self clientnotify( "lststnd" );
}
*/

//if ( IsDefined( level.deathcard_laststand_func ) )
//{
// self [[ level.deathcard_laststand_func ]]();
//}
self clear_is_drinking();

self thread remote_revive_watch();

self maps\_zombiemode_score::player_downed_penalty();

self thread last_stand_grenade_save_and_return();

if( sMeansOfDeath != "MOD_SUICIDE" && sMeansOfDeath != "MOD_FALLING" )
{
self maps\_zombiemode_audio::create_and_play_dialog( "general", "revive_down" );
}

bbPrint( "zombie_playerdeaths: round %d playername %s deathtype downed x %f y %f z %f", level.round_number, self.playername, self.origin );

if( IsDefined( level._zombie_minigun_powerup_last_stand_func ) )
{
self [ [ level._zombie_minigun_powerup_last_stand_func ] ]();
}

if( IsDefined( self.intermission ) && self.intermission )
{
//maps\_zombiemode_challenges::doMissionCallback( "playerDied", self );

bbPrint( "zombie_playerdeaths: round %d playername %s deathtype died x %f y %f z %f", level.round_number, self.playername, self.origin );

level waittill( "forever" );
}
}

spawnSpectator()
{
self endon( "disconnect" );
self endon( "spawned_spectator" );
self notify( "spawned" );
self notify( "end_respawn" );

if( level.intermission )
{
return;
}

if( IsDefined( level.no_spectator ) && level.no_spectator )
{
wait( 3 );
ExitLevel();
}

// The check_for_level_end looks for this
self.is_zombie = true;

// Remove all reviving abilities
self notify ( "zombified" );

if( IsDefined( self.revivetrigger ) )
{
self.revivetrigger delete();
self.revivetrigger = undefined;
}

self.zombification_time = GetTime(); //set time when player died

resetTimeout();

// Stop shellshock and rumble
self StopShellshock();
self StopRumble( "damage_heavy" );

self.sessionstate = "spectator";
self.spectatorclient = -1;

self remove_from_spectate_list();

self.maxhealth = self.health;
self.shellshocked = false;
self.inWater = false;
self.friendlydamage = undefined;
self.hasSpawned = true;
self.spawnTime = GetTime();
self.afk = false;

println( "*************************Zombie Spectator***" );
self detachAll();

self setSpectatePermissions( true );
self thread spectator_thread();

self Spawn( self.origin, self.angles );
self notify( "spawned_spectator" );
}

setSpectatePermissions( isOn )
{
self AllowSpectateTeam( "allies", isOn );
self AllowSpectateTeam( "axis", false );
self AllowSpectateTeam( "freelook", false );
self AllowSpectateTeam( "none", false );
}

spectator_thread()
{
self endon( "disconnect" );
self endon( "spawned_player" );

/* we are not currently supporting the shared screen tech
if( IsSplitScreen() )
{
last_alive = undefined;
players = get_players();

for( i = 0; i {
if( !players[i].is_zombie )
{
last_alive = players[i];
}
}

share_screen( last_alive, true );

return;
}
*/

// self thread spectator_toggle_3rd_person();
}

spectator_toggle_3rd_person()
{
self endon( "disconnect" );
self endon( "spawned_player" );

third_person = true;
self set_third_person( true );
// self NotifyOnCommand( "toggle_3rd_person", "weapnext" );

// while( 1 )
// {
// self waittill( "toggle_3rd_person" );
//
// if( third_person )
// {
// third_person = false;
// self set_third_person( false );
// wait( 0.5 );
// }
// else
// {
// third_person = true;
// self set_third_person( true );
// wait( 0.5 );
// }
// }
}


set_third_person( value )
{
if( value )
{
self SetClientDvars( "cg_thirdPerson", "1",
"cg_fov", "40",
"cg_thirdPersonAngle", "354" );

self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
}
else
{
self SetClientDvars( "cg_thirdPerson", "0",
"cg_fov", "65",
"cg_thirdPersonAngle", "0" );

self setDepthOfField( 0, 0, 512, 4000, 4, 0 );
}
}

last_stand_revive()
{
level endon( "between_round_over" );

players = getplayers();

for ( i = 0; i {
if ( players[i] maps\_laststand::player_is_in_laststand() && players[i].revivetrigger.beingRevived == 0 )
{
players[i] maps\_laststand::auto_revive();
}
}
}

// ww: arrange the last stand pistols so when it come time to choose which one they are inited
last_stand_pistol_rank_init()
{
level.pistol_values = [];

flag_wait( "_start_zm_pistol_rank" );

if( flag( "solo_game" ) )
{
// ww: in a solo game the ranking of the pistols is a bit different based on the upgraded 1911 swap
// any pistol ranked 8 or lower will be ignored and the player will be given the upgraded 1911
level.pistol_values[ level.pistol_values.size ] = "m1911_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_bowie_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_bowie_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75dw_zm";
level.pistol_values[ level.pistol_values.size ] = "python_zm";
level.pistol_values[ level.pistol_values.size ] = "python_upgraded_zm"; // ww: this is spot 8, anything scoring lower than this should be replaced
level.pistol_values[ level.pistol_values.size ] = "cz75_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75dw_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "m1911_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "ray_gun_zm";
level.pistol_values[ level.pistol_values.size ] = "freezegun_zm";
level.pistol_values[ level.pistol_values.size ] = "ray_gun_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "freezegun_upgraded_zm";
}
else
{
level.pistol_values[ level.pistol_values.size ] = "m1911_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_bowie_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75dw_zm";
level.pistol_values[ level.pistol_values.size ] = "python_zm";
level.pistol_values[ level.pistol_values.size ] = "python_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "cz75dw_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "m1911_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "knife_ballistic_bowie_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "ray_gun_zm";
level.pistol_values[ level.pistol_values.size ] = "freezegun_zm";
level.pistol_values[ level.pistol_values.size ] = "ray_gun_upgraded_zm";
level.pistol_values[ level.pistol_values.size ] = "freezegun_upgraded_zm";
}

}

// ww: changing the _laststand scripts to this one so we interfere with SP less
last_stand_pistol_swap()
{
self GiveWeapon( self.laststandpistol );
ammoclip = WeaponClipSize( self.laststandpistol );

if( IsDefined( self._special_solo_pistol_swap ) && self._special_solo_pistol_swap == 1 )
{
self._special_solo_pistol_swap = 0;
self.hadpistol = false;
}


if ( self.laststandpistol == "ray_gun_zm" || self.laststandpistol == "ray_gun_upgraded_zm" )
{
self SetWeaponAmmoClip( self.laststandpistol, ammoclip );
self SetWeaponAmmoStock( self.laststandpistol, 0 );

}
else
{
self SetWeaponAmmoStock( self.laststandpistol, ammoclip * 2 );
}

// self GiveWeapon( "knife_zm" );
self SwitchToWeapon( self.laststandpistol );

}

// ww: make sure the player has the best pistol when they go in to last stand
last_stand_best_pistol()
{
pistol_array = [];

current_weapons = self GetWeaponsListPrimaries();

for( i = 0; i {
// make sure the weapon is a pistol
if( WeaponClass( current_weapons[i] ) == "pistol" )
{
pistol_array_index = pistol_array.size; // set up the spot in the array
pistol_array[ pistol_array_index ] = SpawnStruct(); // struct to store info on

pistol_array[ pistol_array_index ].gun = current_weapons[i];
pistol_array[ pistol_array_index ].value = 0; // add a value in case a new weapon is introduced that hasn't been set up in level.pistol_values

// compare the current weapon to the level.pistol_values to see what the value is
for( j = 0; j {
if( level.pistol_values[j] == current_weapons[i] )
{
pistol_array[ pistol_array_index ].value = j;
break;
}
}
}
}

self.laststandpistol = last_stand_compare_pistols( pistol_array );
}

// ww: compares the array passed in for the highest valued pistol
last_stand_compare_pistols( struct_array )
{
if( !IsArray( struct_array ) || struct_array.size {
return level.laststandpistol; // nothing in the array then give the level last stand pistol
}

highest_score_pistol = struct_array[0]; // first time through give the first one to the highest score

for( i = 1; i {
if( struct_array[i].value > highest_score_pistol.value )
{
highest_score_pistol = struct_array[i];
}
}

if( flag( "solo_game" ) )
{
self._special_solo_pistol_swap = 0; // ww: this way the weapon knows to pack texture when given
if( highest_score_pistol.value {
self._special_solo_pistol_swap = 1;
return level.laststandpistol; // ww: if it scores too low the player gets the 1911 upgraded
}
else
{
return highest_score_pistol.gun; // ww: gun is high in ranking and won't be replaced
}
}
else // ww: happens when not in solo
{
return highest_score_pistol.gun;
}

}

// ww: override function for saving player pistol ammo count
last_stand_save_pistol_ammo()
{
weapon_inventory = self GetWeaponsList();
self.stored_weapon_info = [];

for( i = 0; i {
weapon = weapon_inventory[i];

if ( WeaponClass( weapon ) == "pistol" )
{
self.stored_weapon_info[ weapon ] = SpawnStruct();
self.stored_weapon_info[ weapon ].clip_amt = self GetWeaponAmmoClip( weapon );
self.stored_weapon_info[ weapon ].stock_amt = self GetWeaponAmmoStock( weapon );
}
}

self last_stand_best_pistol();
}

// ww: override to restore the player's pistol ammo after being picked up
last_stand_restore_pistol_ammo()
{
if( !IsDefined( self.stored_weapon_info ) )
{
return;
}

weapon_inventory = self GetWeaponsList();
weapon_to_restore = GetArrayKeys( self.stored_weapon_info );

for( i = 0; i {
weapon = weapon_inventory[i];

for( j = 0; j {
check_weapon = weapon_to_restore[j];

if( weapon == check_weapon )
{
self SetWeaponAmmoClip( weapon_to_restore[j], self.stored_weapon_info[ weapon_to_restore[j] ].clip_amt );
self SetWeaponAmmoStock( weapon_to_restore[j], self.stored_weapon_info[ weapon_to_restore[j] ].stock_amt );
break;
}
}
}
}

// ww: changes the last stand pistol to the upgraded 1911s if it is solo
zombiemode_solo_last_stand_pistol()
{
level.laststandpistol = "m1911_upgraded_zm";
}

// ww: zeros out the player's grenades until they revive
last_stand_grenade_save_and_return()
{
self endon( "death" );

frag_nade_amt = 0;
has_frag = false;
monkey_nade_amt = 0;
has_monkey = false;

// figure out which nades this player has
weapons_on_player = self GetWeaponsList();
for( i = 0; i {
if( weapons_on_player[i] == "frag_grenade_zm" )
{
has_frag = true;
frag_nade_amt = self GetWeaponAmmoClip( "frag_grenade_zm" );
self SetWeaponAmmoClip( "frag_grenade_zm", 0 );
}
else if( weapons_on_player[i] == "zombie_cymbal_monkey" )
{
has_monkey = true;
monkey_nade_amt = self GetWeaponAmmoClip( "zombie_cymbal_monkey" );
self SetWeaponAmmoClip( "zombie_cymbal_monkey", 0 );
}
}

self waittill( "player_revived" );

if( has_frag )
{
if( frag_nade_amt > self GetWeaponAmmoClip( "frag_grenade_zm" ) )
{
self SetWeaponAmmoClip( "frag_grenade_zm", frag_nade_amt );
}
}

if( has_monkey )
{
if( monkey_nade_amt > self GetWeaponAmmoClip( "zombie_cymbal_monkey" ) )
{
self SetWeaponAmmoClip( "zombie_cymbal_monkey", monkey_nade_amt );
}

}
}

spectators_respawn()
{
level endon( "between_round_over" );

if( !IsDefined( level.zombie_vars["spectators_respawn"] ) || !level.zombie_vars["spectators_respawn"] )
{
return;
}

if( !IsDefined( level.custom_spawnPlayer ) )
{
// Custom spawn call for when they respawn from spectator
level.custom_spawnPlayer = ::spectator_respawn;
}

while( 1 )
{
players = get_players();
for( i = 0; i {
if( players[i].sessionstate == "spectator" )
{
players[i] [[level.spawnPlayer]]();
if (isDefined(level.script) && level.round_number > 6 && players[i].score {
players[i].old_score = players[i].score;
players[i].score = 1500;
players[i] maps\_zombiemode_score::set_player_score_hud();
}
}
}

wait( 1 );
}
}

spectator_respawn()
{
println( "*************************Respawn Spectator***" );
assert( IsDefined( self.spectator_respawn ) );

origin = self.spectator_respawn.origin;
angles = self.spectator_respawn.angles;

self setSpectatePermissions( false );

new_origin = undefined;


new_origin = check_for_valid_spawn_near_team( self );


if( IsDefined( new_origin ) )
{
self Spawn( new_origin, angles );
}
else
{
self Spawn( origin, angles );
}


/* we are not currently supporting the shared screen tech
if( IsSplitScreen() )
{
last_alive = undefined;
players = get_players();

for( i = 0; i {
if( !players[i].is_zombie )
{
last_alive = players[i];
}
}

share_screen( last_alive, false );
}
*/

//DCS: if player has claymores, take away.
if(IsDefined(self.has_claymores))
{
self.has_claymores = undefined;
self TakeWeapon("claymore_zm");
}

self.has_betties = undefined;
self.is_burning = undefined;
self.abilities = [];

// The check_for_level_end looks for this
self.is_zombie = false;
self.ignoreme = false;

setClientSysState("lsm", "0", self); // Notify client last stand ended.
self RevivePlayer();

self notify( "spawned_player" );

// Penalize the player when we respawn, since he 'died'
self maps\_zombiemode_score::player_reduce_points( "died" );

//DCS: make bowie & claymore trigger available again.
bowie_triggers = GetEntArray( "bowie_upgrade", "targetname" );
// ww: player needs to reset trigger knowledge without claiming full ownership
self._bowie_zm_equipped = undefined;
players = get_players();
for( i = 0; i {
bowie_triggers[i] SetVisibleToAll();
// check the player to see if he has the bowie, if they do trigger goes invisible
for( j = 0; j {
if( IsDefined( players[j]._bowie_zm_equipped ) && players[j]._bowie_zm_equipped == 1 )
{
bowie_triggers[i] SetInvisibleToPlayer( players[j] );
}
}
}

// ww: inside _zombiemode_claymore the claymore triggers are fixed for players who haven't bought them
// to see them after someone respawns from bleedout
// it isn't the best way to do it but it is late in the project and probably better if i don't modify it
// unless a bug comes through on it
claymore_triggers = getentarray("claymore_purchase","targetname");
for(i = 0; i {
claymore_triggers[i] SetVisibleToPlayer(self);
claymore_triggers[i].claymores_triggered = false;
}

self thread player_zombie_breadcrumb();

return true;
}

check_for_valid_spawn_near_team( revivee )
{

players = get_players();
spawn_points = getstructarray("player_respawn_point", "targetname");
closest_group = undefined;
closest_distance = 100000000;
backup_group = undefined;
backup_distance = 100000000;

if( spawn_points.size == 0 )
return undefined;

// Look for the closest group that is within the specified ideal distances
// If we can't find one within a valid area, use the closest unlocked group.
for( i = 0; i {
if( is_player_valid( players[i] ) )
{
for( j = 0 ; j {
if( isdefined(spawn_points[i].script_int) )
ideal_distance = spawn_points[i].script_int;
else
ideal_distance = 1000;

if ( spawn_points[j].locked == false )
{
distance = DistanceSquared( players[i].origin, spawn_points[j].origin );
if( distance {
if ( distance {
closest_distance = distance;
closest_group = j;
}
}
else
{
if ( distance {
backup_group = j;
backup_distance = distance;
}
}
}
}
}
// If we don't have a closest_group, let's use the backup
if ( !IsDefined( closest_group ) )
{
closest_group = backup_group;
}

if ( IsDefined( closest_group ) )
{
spawn_array = getstructarray( spawn_points[closest_group].target, "targetname" );

for( k = 0; k {
if( spawn_array[k].script_int == (revivee.entity_num + 1) )
{
return spawn_array[k].origin;
}
}

return spawn_array[0].origin;
}
}

return undefined;

}


get_players_on_team(exclude)
{

teammates = [];

players = get_players();
for(i=0;i {
//check to see if other players on your team are alive and not waiting to be revived
if(players[i].spawn_side == self.spawn_side && !isDefined(players[i].revivetrigger) && players[i] != exclude )
{
teammates[teammates.size] = players[i];
}
}

return teammates;
}



get_safe_breadcrumb_pos( player )
{
players = get_players();
valid_players = [];

min_dist = 150 * 150;
for( i = 0; i {
if( !is_player_valid( players[i] ) )
{
continue;
}

valid_players[valid_players.size] = players[i];
}

for( i = 0; i {
count = 0;
for( q = 1; q {
if( DistanceSquared( player.zombie_breadcrumbs[q], valid_players[i].origin ) {
continue;
}

count++;
if( count == valid_players.size )
{
return player.zombie_breadcrumbs[q];
}
}
}

return undefined;
}

default_max_zombie_func( max_num )
{
max = max_num;

if ( level.first_round )
{
max = int( max_num * 0.25 );
}
else if (level.round_number {
max = int( max_num * 0.3 );
}
else if (level.round_number {
max = int( max_num * 0.5 );
}
else if (level.round_number {
max = int( max_num * 0.7 );
}
else if (level.round_number {
max = int( max_num * 0.9 );
}

return max;
}

round_spawning()
{
level endon( "intermission" );
level endon( "end_of_round" );
level endon( "restart_round" );
/#
level endon( "kill_round" );
#/

if( level.intermission )
{
return;
}

if( level.enemy_spawns.size {
ASSERTMSG( "No active spawners in the map. Check to see if the zone is active and if it's pointing to spawners." );
return;
}

/#
if ( GetDvarInt( #"zombie_cheat" ) == 2 || GetDvarInt( #"zombie_cheat" ) >= 4 )
{
return;
}
#/

ai_calculate_health( level.round_number );

count = 0;

//CODER MOD: TOMMY K
players = get_players();
for( i = 0; i {
players[i].zombification_time = 0;
}

max = level.zombie_vars["zombie_max_ai"];

multiplier = level.round_number / 5;
if( multiplier {
multiplier = 1;
}

// After round 10, exponentially have more AI attack the player
if( level.round_number >= 10 )
{
multiplier *= level.round_number * 0.15;
}

player_num = get_players().size;

if( player_num == 1 )
{
max += int( ( 0.5 * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
}
else
{
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;
}

// Now set the total for the new round, except when it's already been set by the
// kill counter.
if ( !(IsDefined( level.kill_counter_hud ) && level.zombie_total > 0) )
{
level.zombie_total = [[ level.max_zombie_func ]]( max );
}

if ( level.round_number {
level thread zombie_speed_up();
}

mixed_spawns = 0; // Number of mixed spawns this round. Currently means number of dogs in a mixed round

// DEBUG HACK:
//max = 1;
old_spawn = undefined;
// while( level.zombie_total > 0 )
while( 1 )
{
while( get_enemy_count() > 31 || level.zombie_total {
wait( 0.1 );
}

// added ability to pause zombie spawning
if ( !flag("spawn_zombies" ) )
{
flag_wait( "spawn_zombies" );
}

spawn_point = level.enemy_spawns[RandomInt( level.enemy_spawns.size )];

if( !IsDefined( old_spawn ) )
{
old_spawn = spawn_point;
}
else if( Spawn_point == old_spawn )
{
spawn_point = level.enemy_spawns[RandomInt( level.enemy_spawns.size )];
}
old_spawn = spawn_point;

// iPrintLn(spawn_point.targetname + " " + level.zombie_vars["zombie_spawn_delay"]);

// MM Mix in dog spawns...
if ( IsDefined( level.mixed_rounds_enabled ) && level.mixed_rounds_enabled == 1 )
{
spawn_dog = false;
if ( level.round_number > 30 )
{
if ( RandomInt(100) {
spawn_dog = true;
}
}
else if ( level.round_number > 25 && mixed_spawns {
if ( RandomInt(100) {
spawn_dog = true;
}
}
else if ( level.round_number > 20 && mixed_spawns {
if ( RandomInt(100) {
spawn_dog = true;
}
}
else if ( level.round_number > 15 && mixed_spawns {
if ( RandomInt(100) {
spawn_dog = true;
}
}

if ( spawn_dog )
{
keys = GetArrayKeys( level.zones );
for ( i=0; i {
if ( level.zones[ keys[i] ].is_occupied )
{
akeys = GetArrayKeys( level.zones[ keys[i] ].adjacent_zones );
for ( k=0; k {
if ( level.zones[ akeys[k] ].is_active &&
!level.zones[ akeys[k] ].is_occupied &&
level.zones[ akeys[k] ].dog_locations.size > 0 )
{
maps\_zombiemode_ai_dogs::special_dog_spawn( undefined, 1 );
level.zombie_total--;
wait_network_frame();
}
}
}
}
}
}

ai = spawn_zombie( spawn_point );
if( IsDefined( ai ) )
{
level.zombie_total--;
ai thread round_spawn_failsafe();
count++;
}

wait( level.zombie_vars["zombie_spawn_delay"] );
wait_network_frame();
}
}

//
// Make the last few zombies run
//
zombie_speed_up()
{
if( level.round_number {
return;
}

level endon( "intermission" );
level endon( "end_of_round" );
level endon( "restart_round" );
/#
level endon( "kill_round" );
#/

// Wait until we've finished spawning
while ( level.zombie_total > 4 )
{
wait( 2.0 );
}

// Now wait for these guys to get whittled down
num_zombies = get_enemy_count();
while( num_zombies > 3 )
{
wait( 2.0 );

num_zombies = get_enemy_count();
}

zombies = GetAiSpeciesArray( "axis", "all" );
while( zombies.size > 0 )
{
if( zombies.size == 1 && zombies[0].has_legs == true )
{
var = randomintrange(1, 4);
zombies[0] set_run_anim( "sprint" + var );
zombies[0].run_combatanim = level.scr_anim[zombies[0].animname]["sprint" + var];
}
wait(0.5);
zombies = GetAiSpeciesArray( "axis", "all" );
}
}

// TESTING: spawn one zombie at a time
round_spawning_test()
{
while (true)
{
spawn_point = level.enemy_spawns[RandomInt( level.enemy_spawns.size )]; // grab a random spawner

ai = spawn_zombie( spawn_point );
ai waittill("death");

wait 5;
}
}
/////////////////////////////////////////////////////////

// round_text( text )
// {
// if( level.first_round )
// {
// intro = true;
// }
// else
// {
// intro = false;
// }
//
// hud = create_simple_hud();
// hud.horzAlign = "center";
// hud.vertAlign = "middle";
// hud.alignX = "center";
// hud.alignY = "middle";
// hud.y = -100;
// hud.foreground = 1;
// hud.fontscale = 16.0;
// hud.alpha = 0;
// hud.color = ( 1, 1, 1 );
//
// hud SetText( text );
// hud FadeOverTime( 1.5 );
// hud.alpha = 1;
// wait( 1.5 );
//
// if( intro )
// {
// wait( 1 );
// level notify( "intro_change_color" );
// }
//
// hud FadeOverTime( 3 );
// //hud.color = ( 0.8, 0, 0 );
// hud.color = ( 0.21, 0, 0 );
// wait( 3 );
//
// if( intro )
// {
// level waittill( "intro_hud_done" );
// }
//
// hud FadeOverTime( 1.5 );
// hud.alpha = 0;
// wait( 1.5 );
// hud destroy();
// }


// Allows the round to be paused. Displays a countdown timer.
//
round_pause( delay )
{
if ( !IsDefined( delay ) )
{
delay = 30;
}

level.countdown_hud = create_counter_hud();
level.countdown_hud SetValue( delay );
level.countdown_hud.color = ( 1, 1, 1 );
level.countdown_hud.alpha = 1;
level.countdown_hud FadeOverTime( 2.0 );
wait( 2.0 );

level.countdown_hud.color = ( 0.21, 0, 0 );
level.countdown_hud FadeOverTime( 3.0 );
wait(3);

while (delay >= 1)
{
wait (1);
delay--;
level.countdown_hud SetValue( delay );
}

// Zero! Play end sound
players = GetPlayers();
for (i=0; i {
players[i] playlocalsound( "zmb_perks_packa_ready" );
}

level.countdown_hud FadeOverTime( 1.0 );
level.countdown_hud.color = (1,1,1);
level.countdown_hud.alpha = 0;
wait( 1.0 );

level.countdown_hud destroy_hud();
}


// Zombie spawning
//
round_start()
{
if ( IsDefined(level.round_prestart_func) )
{
[[ level.round_prestart_func ]]();
}
else
{
wait( 2 );
}

level.zombie_health = level.zombie_vars["zombie_health_start"];

// so players get init'ed with grenades
players = get_players();
for (i = 0; i {
players[i] giveweapon( "frag_grenade_zm" );
players[i] setweaponammoclip( "frag_grenade_zm", 0);
players[i] SetClientDvars( "ammoCounterHide", "0",
"miniscoreboardhide", "0" );
//players[i] thread maps\_zombiemode_ability::give_round1_abilities();
}

if( getDvarInt( #"scr_writeconfigstrings" ) == 1 )
{
wait(5);
ExitLevel();
return;
}
if( isDefined(level.chests) && isDefined(level.chest_index) )
{
Objective_Add( 0, "active", "Mystery Box", level.chests[level.chest_index].chest_lid.origin, "minimap_icon_mystery_box" );
}

if ( level.zombie_vars["game_start_delay"] > 0 )
{
round_pause( level.zombie_vars["game_start_delay"] );
}

flag_set( "begin_spawning" );

//maps\_zombiemode_solo::init();

level.chalk_hud1 = create_chalk_hud();
// if( level.round_number >= 1 && level.round_number // {
// level.chalk_hud1 SetShader( "hud_chalk_" + level.round_number, 64, 64 );
// }
// else if ( level.round_number >= 5 && level.round_number // {
// level.chalk_hud1 SetShader( "hud_chalk_5", 64, 64 );
// }
level.chalk_hud2 = create_chalk_hud( 64 );

// level waittill( "introscreen_done" );

if( !isDefined(level.round_spawn_func) )
{
level.round_spawn_func = ::round_spawning;
}
/#
if (GetDvarInt( #"zombie_rise_test"))
{
level.round_spawn_func = ::round_spawning_test; // FOR TESTING, one zombie at a time, no round advancement
}
#/

if ( !isDefined(level.round_wait_func) )
{
level.round_wait_func = ::round_wait;
}

if ( !IsDefined(level.round_think_func) )
{
level.round_think_func = ::round_think;
}

if( level.mutators["mutator_fogMatch"] )
{
players = get_players();
for( i = 0; i {
players[i] thread set_fog( 729.34, 971.99, 338.336, 398.623, 0.58, 0.60, 0.56, 3 );
}
}

level thread [[ level.round_think_func ]]();
}


//
//
create_chalk_hud( x )
{
if( !IsDefined( x ) )
{
x = 0;
}

hud = create_simple_hud();
hud.alignX = "left";
hud.alignY = "bottom";
hud.horzAlign = "user_left";
hud.vertAlign = "user_bottom";
hud.color = ( 0.21, 0, 0 );
hud.x = x;
hud.y = -4;
hud.alpha = 0;
hud.fontscale = 32.0;

hud SetShader( "hud_chalk_1", 64, 64 );

return hud;
}


//
//
destroy_chalk_hud()
{
if( isDefined( level.chalk_hud1 ) )
{
level.chalk_hud1 Destroy();
level.chalk_hud1 = undefined;
}

if( isDefined( level.chalk_hud2 ) )
{
level.chalk_hud2 Destroy();
level.chalk_hud2 = undefined;
}
}


//
// Let's the players know that you need power to open these
play_door_dialog()
{
level endon( "power_on" );
self endon ("warning_dialog");
timer = 0;

while(1)
{
wait(0.05);
players = get_players();
for(i = 0; i {
dist = distancesquared(players[i].origin, self.origin );
if(dist > 70*70)
{
timer =0;
continue;
}
while(dist {
wait(0.5);
timer++;
}
if(dist > 70*70 && timer >= 3)
{
self playsound("door_deny");

players[i] maps\_zombiemode_audio::create_and_play_dialog( "general", "door_deny" );
wait(3);
self notify ("warning_dialog");
//iprintlnbold("warning_given");
}
}
}
}

wait_until_first_player()
{
players = get_players();
if( !IsDefined( players[0] ) )
{
level waittill( "first_player_ready" );
}
}

//
// Set the current round number hud display
chalk_one_up()
{
huds = [];
huds[0] = level.chalk_hud1;
huds[1] = level.chalk_hud2;

// Hud1 shader
if( level.round_number >= 1 && level.round_number {
huds[0] SetShader( "hud_chalk_" + level.round_number, 64, 64 );
}
else if ( level.round_number >= 5 && level.round_number {
huds[0] SetShader( "hud_chalk_5", 64, 64 );
}

// Hud2 shader
if( level.round_number > 5 && level.round_number {
huds[1] SetShader( "hud_chalk_" + ( level.round_number - 5 ), 64, 64 );
}

// Display value
if ( IsDefined( level.chalk_override ) )
{
huds[0] SetText( level.chalk_override );
huds[1] SetText( " " );
}
else if( level.round_number {
huds[1] SetText( " " );
}
else if( level.round_number > 10 )
{
huds[0].fontscale = 32;
huds[0] SetValue( level.round_number );
huds[1] SetText( " " );
}

if(!IsDefined(level.doground_nomusic))
{
level.doground_nomusic = 0;
}
if( level.first_round )
{
intro = true;
level thread play_level_start_vox_delayed();
}
else
{
intro = false;
}

round = undefined;
if( intro )
{
// Create "ROUND" hud text
round = create_simple_hud();
round.alignX = "center";
round.alignY = "bottom";
round.horzAlign = "user_center";
round.vertAlign = "user_bottom";
round.fontscale = 16;
round.color = ( 1, 1, 1 );
round.x = 0;
round.y = -265;
round.alpha = 0;
round SetText( &"ZOMBIE_ROUND" );

// huds[0] FadeOverTime( 0.05 );
huds[0].color = ( 1, 1, 1 );
huds[0].alpha = 0;
huds[0].horzAlign = "user_center";
huds[0].x = -5;
huds[0].y = -200;

huds[1] SetText( " " );

// Fade in white
round FadeOverTime( 1 );
round.alpha = 1;

huds[0] FadeOverTime( 1 );
huds[0].alpha = 1;

wait( 1 );

// Fade to red
round FadeOverTime( 2 );
round.color = ( 0.21, 0, 0 );

huds[0] FadeOverTime( 2 );
huds[0].color = ( 0.21, 0, 0 );
wait(2);
}
else
{
for ( i=0; i {
huds[i] FadeOverTime( 0.5 );
huds[i].alpha = 0;
}
wait( 0.5 );
}

// if( (level.round_number = 11) && IsDefined( level.chalk_hud2 ) )
// {
// huds[1] = undefined;
// }
//
for ( i=0; i {
huds[i] FadeOverTime( 2 );
huds[i].alpha = 1;
}

if( intro )
{
wait( 3 );

if( IsDefined( round ) )
{
round FadeOverTime( 1 );
round.alpha = 0;
}

wait( 0.25 );

level notify( "intro_hud_done" );
huds[0] MoveOverTime( 1.75 );
huds[0].horzAlign = "user_left";
// huds[0].x = 0;
huds[0].y = -4;
wait( 2 );

round destroy_hud();
}
else
{
for ( i=0; i {
huds[i].color = ( 1, 1, 1 );
}
}

// Okay now wait just a bit to let the number set in
if ( !intro )
{
wait( 2 );

for ( i=0; i {
huds[i] FadeOverTime( 1 );
huds[i].color = ( 0.21, 0, 0 );
}
}

ReportMTU(level.round_number); // In network debug instrumented builds, causes network spike report to generate.

// Remove any override set since we're done with it
if ( IsDefined( level.chalk_override ) )
{
level.chalk_override = undefined;
}
}


// Flash the round display at the end of the round
//
chalk_round_over()
{
huds = [];
huds[huds.size] = level.chalk_hud1;
huds[huds.size] = level.chalk_hud2;

if( level.round_number 10 )
{
level.chalk_hud2 SetText( " " );
}

time = level.zombie_vars["zombie_between_round_time"];
if ( time > 3 )
{
time = time - 2; // add this deduction back in at the bottom
}

for( i = 0; i {
if( IsDefined( huds[i] ) )
{
huds[i] FadeOverTime( time * 0.25 );
huds[i].color = ( 1, 1, 1 );
}
}

// Pulse
fade_time = 0.5;
steps = ( time * 0.5 ) / fade_time;
for( q = 0; q {
for( i = 0; i {
if( !IsDefined( huds[i] ) )
{
continue;
}

huds[i] FadeOverTime( fade_time );
huds[i].alpha = 0;
}

wait( fade_time );

for( i = 0; i {
if( !IsDefined( huds[i] ) )
{
continue;
}

huds[i] FadeOverTime( fade_time );
huds[i].alpha = 1;
}

wait( fade_time );
}

for( i = 0; i {
if( !IsDefined( huds[i] ) )
{
continue;
}

huds[i] FadeOverTime( time * 0.25 );
// huds[i].color = ( 0.8, 0, 0 );
huds[i].color = ( 0.21, 0, 0 );
huds[i].alpha = 0;
}

wait ( 2.0 );
}

round_think()
{
for( ;; )
{
//////////////////////////////////////////
//designed by prod DT#36173
maxreward = 50 * level.round_number;
if ( maxreward > 500 )
maxreward = 500;
level.zombie_vars["rebuild_barrier_cap_per_round"] = maxreward;
//////////////////////////////////////////

level.pro_tips_start_time = GetTime();
level.zombie_last_run_time = GetTime(); // Resets the last time a zombie ran

level thread maps\_zombiemode_audio::change_zombie_music( "round_start" );
chalk_one_up();
// round_text( &"ZOMBIE_ROUND_BEGIN" );

maps\_zombiemode_powerups::powerup_round_start();

players = get_players();
array_thread( players, maps\_zombiemode_blockers::rebuild_barrier_reward_reset );

//array_thread( players, maps\_zombiemode_ability::giveHardpointItems );

level thread award_grenades_for_survivors();

bbPrint( "zombie_rounds: round %d player_count %d", level.round_number, players.size );

level.round_start_time = GetTime();
level thread [[level.round_spawn_func]]();

level notify( "start_of_round" );

[[level.round_wait_func]]();

level.first_round = false;
level notify( "end_of_round" );

level thread maps\_zombiemode_audio::change_zombie_music( "round_end" );

UploadStats();

if ( 1 != players.size )
{
level thread spectators_respawn();
//level thread last_stand_revive();
}

// round_text( &"ZOMBIE_ROUND_END" );
level chalk_round_over();

// here's the difficulty increase over time area
timer = level.zombie_vars["zombie_spawn_delay"];
if ( timer > 0.08 )
{
level.zombie_vars["zombie_spawn_delay"] = timer * 0.95;
}
else if ( timer {
level.zombie_vars["zombie_spawn_delay"] = 0.08;
}

//
// Increase the zombie move speed
level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"];

// iPrintlnBold( "End of Round " + level.round_number );
// for ( i=0; i // {
// iPrintlnBold( "Team Pool "+(i+1)+" score: ", level.team_pool[i].score_total );
// }
//
// players = get_players();
// for ( p=0; p // {
// iPrintlnBold( "Total Player "+(p+1)+" score : "+ players[p].score_total );
// }

level.round_number++;

level notify( "between_round_over" );
}
}


award_grenades_for_survivors()
{
players = get_players();

for (i = 0; i {
if (!players[i].is_zombie)
{
if( !players[i] HasWeapon( "frag_grenade_zm" ) )
{
players[i] GiveWeapon( "frag_grenade_zm" );
players[i] SetWeaponAmmoClip( "frag_grenade_zm", 0 );
}

if ( players[i] GetFractionMaxAmmo( "frag_grenade_zm") {
players[i] SetWeaponAmmoClip( "frag_grenade_zm", 2 );
}
else if (players[i] GetFractionMaxAmmo( "frag_grenade_zm") {
players[i] SetWeaponAmmoClip( "frag_grenade_zm", 3 );
}
else
{
players[i] SetWeaponAmmoClip( "frag_grenade_zm", 4 );
}
}
}
}

ai_calculate_health( round_number )
{
level.zombie_health = level.zombie_vars["zombie_health_start"];
for ( i=2; i {
// After round 10, get exponentially harder
if( i >= 10 )
{
level.zombie_health += Int( level.zombie_health * level.zombie_vars["zombie_health_increase_multiplier"] );
}
else
{
level.zombie_health = Int( level.zombie_health + level.zombie_vars["zombie_health_increase"] );
}
}
}


//put the conditions in here which should
//cause the failsafe to reset
round_spawn_failsafe()
{
self endon("death");//guy just died

//////////////////////////////////////////////////////////////
//FAILSAFE "hack shit" DT#33203
//////////////////////////////////////////////////////////////
prevorigin = self.origin;
while(1)
{
if( !level.zombie_vars["zombie_use_failsafe"] )
{
return;
}

wait( 30 );

//if i've torn a board down in the last 5 seconds, just
//wait 30 again.
if ( isDefined(self.lastchunk_destroy_time) )
{
if ( (GetTime() - self.lastchunk_destroy_time) continue;
}

//fell out of world
if ( self.origin[2] {
self dodamage( self.health + 100, (0,0,0) );
break;
}

//hasnt moved 24 inches in 30 seconds?
if ( DistanceSquared( self.origin, prevorigin ) {
// DEBUG HACK
self dodamage( self.health + 100, (0,0,0) );
break;
}

prevorigin = self.origin;
}
//////////////////////////////////////////////////////////////
//END OF FAILSAFE "hack shit"
//////////////////////////////////////////////////////////////
}

// Waits for the time and the ai to die
round_wait()
{
/#
if (GetDvarInt( #"zombie_rise_test"))
{
level waittill("forever"); // TESTING: don't advance rounds
}
#/

/#
if ( GetDvarInt( #"zombie_cheat" ) == 2 || GetDvarInt( #"zombie_cheat" ) >= 4 )
{
level waittill("forever");
}
#/

wait( 1 );

if( flag("dog_round" ) )
{
wait(7);
while( level.dog_intermission )
{
wait(0.5);
}
}
else
{
while( get_enemy_count() > 0 || level.zombie_total > 0 || level.intermission )
{
if( flag( "end_round_wait" ) )
{
return;
}
wait( 1.0 );
}
}
}


is_friendly_fire_on()
{
return level.mutators[ "mutator_friendlyFire" ];
}


can_revive( reviver )
{
if( self HasWeapon( "minigun_zm" ) )
{
return false;
}

return true;
}

Link to comment

Part 3...note last 3 posts are from same document. Character restrictions limit my posting...



zombify_player()
{
self maps\_zombiemode_score::player_died_penalty();

bbPrint( "zombie_playerdeaths: round %d playername %s deathtype died x %f y %f z %f", level.round_number, self.playername, self.origin );

if ( IsDefined( level.deathcard_spawn_func ) )
{
self [[level.deathcard_spawn_func]]();
}

if( !IsDefined( level.zombie_vars["zombify_player"] ) || !level.zombie_vars["zombify_player"] )
{
//if ( !self maps\_zombiemode_solo::solo_should_restart() )
//{
self thread spawnSpectator();
//}

return;
}

self.ignoreme = true;
self.is_zombie = true;
self.zombification_time = GetTime();

self.team = "axis";
self notify( "zombified" );

if( IsDefined( self.revivetrigger ) )
{
self.revivetrigger Delete();
}
self.revivetrigger = undefined;

self setMoveSpeedScale( 0.3 );
self reviveplayer();

self TakeAllWeapons();
//self starttanning();
self GiveWeapon( "zombie_melee", 0 );
self SwitchToWeapon( "zombie_melee" );
self DisableWeaponCycling();
self DisableOffhandWeapons();
self VisionSetNaked( "zombie_turned", 1 );

maps\_utility::setClientSysState( "zombify", 1, self ); // Zombie grain goooo

self thread maps\_zombiemode_spawner::zombie_eye_glow();

// set up the ground ref ent
self thread injured_walk();
// allow for zombie attacks, but they lose points?

self thread playerzombie_player_damage();
self thread playerzombie_soundboard();
}

playerzombie_player_damage()
{
self endon( "death" );
self endon( "disconnect" );

self thread playerzombie_infinite_health(); // manually keep regular health up
self.zombiehealth = level.zombie_health;

// enable PVP damage on this guy
// self EnablePvPDamage();

while( 1 )
{
self waittill( "damage", amount, attacker, directionVec, point, type );

if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
{
wait( 0.05 );
continue;
}

self.zombiehealth -= amount;

if( self.zombiehealth {
// "down" the zombie
self thread playerzombie_downed_state();
self waittill( "playerzombie_downed_state_done" );
self.zombiehealth = level.zombie_health;
}
}
}

playerzombie_downed_state()
{
self endon( "death" );
self endon( "disconnect" );

downTime = 15;

startTime = GetTime();
endTime = startTime +( downTime * 1000 );

self thread playerzombie_downed_hud();

self.playerzombie_soundboard_disable = true;
self thread maps\_zombiemode_spawner::zombie_eye_glow_stop();
self DisableWeapons();
self AllowStand( false );
self AllowCrouch( false );
self AllowProne( true );

while( GetTime() {
wait( 0.05 );
}

self.playerzombie_soundboard_disable = false;
self thread maps\_zombiemode_spawner::zombie_eye_glow();
self EnableWeapons();
self AllowStand( true );
self AllowCrouch( false );
self AllowProne( false );

self notify( "playerzombie_downed_state_done" );
}

playerzombie_downed_hud()
{
self endon( "death" );
self endon( "disconnect" );

text = NewClientHudElem( self );
text.alignX = "center";
text.alignY = "middle";
text.horzAlign = "user_center";
text.vertAlign = "user_bottom";
text.foreground = true;
text.font = "default";
text.fontScale = 1.8;
text.alpha = 0;
text.color = ( 1.0, 1.0, 1.0 );
text SetText( &"ZOMBIE_PLAYERZOMBIE_DOWNED" );

text.y = -113;
if( IsSplitScreen() )
{
text.y = -137;
}

text FadeOverTime( 0.1 );
text.alpha = 1;

self waittill( "playerzombie_downed_state_done" );

text FadeOverTime( 0.1 );
text.alpha = 0;
}

playerzombie_infinite_health()
{
self endon( "death" );
self endon( "disconnect" );

bighealth = 100000;

while( 1 )
{
if( self.health {
self.health = bighealth;
}

wait( 0.1 );
}
}

playerzombie_soundboard()
{
self endon( "death" );
self endon( "disconnect" );

self.playerzombie_soundboard_disable = false;

self.buttonpressed_use = false;
self.buttonpressed_attack = false;
self.buttonpressed_ads = false;

self.useSound_waitTime = 3 * 1000; // milliseconds
self.useSound_nextTime = GetTime();
useSound = "playerzombie_usebutton_sound";

self.attackSound_waitTime = 3 * 1000;
self.attackSound_nextTime = GetTime();
attackSound = "playerzombie_attackbutton_sound";

self.adsSound_waitTime = 3 * 1000;
self.adsSound_nextTime = GetTime();
adsSound = "playerzombie_adsbutton_sound";

self.inputSound_nextTime = GetTime(); // don't want to be able to do all sounds at once

while( 1 )
{
if( self.playerzombie_soundboard_disable )
{
wait( 0.05 );
continue;
}

if( self UseButtonPressed() )
{
if( self can_do_input( "use" ) )
{
self thread playerzombie_play_sound( useSound );
self thread playerzombie_waitfor_buttonrelease( "use" );
self.useSound_nextTime = GetTime() + self.useSound_waitTime;
}
}
else if( self AttackButtonPressed() )
{
if( self can_do_input( "attack" ) )
{
self thread playerzombie_play_sound( attackSound );
self thread playerzombie_waitfor_buttonrelease( "attack" );
self.attackSound_nextTime = GetTime() + self.attackSound_waitTime;
}
}
else if( self AdsButtonPressed() )
{
if( self can_do_input( "ads" ) )
{
self thread playerzombie_play_sound( adsSound );
self thread playerzombie_waitfor_buttonrelease( "ads" );
self.adsSound_nextTime = GetTime() + self.adsSound_waitTime;
}
}

wait( 0.05 );
}
}

can_do_input( inputType )
{
if( GetTime() {
return false;
}

canDo = false;

switch( inputType )
{
case "use":
if( GetTime() >= self.useSound_nextTime && !self.buttonpressed_use )
{
canDo = true;
}
break;

case "attack":
if( GetTime() >= self.attackSound_nextTime && !self.buttonpressed_attack )
{
canDo = true;
}
break;

case "ads":
if( GetTime() >= self.useSound_nextTime && !self.buttonpressed_ads )
{
canDo = true;
}
break;

default:
ASSERTMSG( "can_do_input(): didn't recognize inputType of " + inputType );
break;
}

return canDo;
}

playerzombie_play_sound( alias )
{
self play_sound_on_ent( alias );
}

playerzombie_waitfor_buttonrelease( inputType )
{
if( inputType != "use" && inputType != "attack" && inputType != "ads" )
{
ASSERTMSG( "playerzombie_waitfor_buttonrelease(): inputType of " + inputType + " is not recognized." );
return;
}

notifyString = "waitfor_buttonrelease_" + inputType;
self notify( notifyString );
self endon( notifyString );

if( inputType == "use" )
{
self.buttonpressed_use = true;
while( self UseButtonPressed() )
{
wait( 0.05 );
}
self.buttonpressed_use = false;
}

else if( inputType == "attack" )
{
self.buttonpressed_attack = true;
while( self AttackButtonPressed() )
{
wait( 0.05 );
}
self.buttonpressed_attack = false;
}

else if( inputType == "ads" )
{
self.buttonpressed_ads = true;
while( self AdsButtonPressed() )
{
wait( 0.05 );
}
self.buttonpressed_ads = false;
}
}

remove_ignore_attacker()
{
self notify( "new_ignore_attacker" );
self endon( "new_ignore_attacker" );
self endon( "disconnect" );

if( !isDefined( level.ignore_enemy_timer ) )
{
level.ignore_enemy_timer = 0.4;
}

wait( level.ignore_enemy_timer );

self.ignoreAttacker = undefined;
}

player_damage_override_cheat( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
{
return 0;
}


//
// player_damage_override
// MUST return the value of the damage override
//
// MM (08/10/09) - Removed calls to PlayerDamageWrapper because it's always called in
// Callback_PlayerDamage now. We just need to return the damage.
//
player_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
{
// WW (8/14/10) - If a player is hit by the crossbow bolt then set them as the holder of the monkey shot
if( sWeapon == "crossbow_explosive_upgraded_zm" && sMeansOfDeath == "MOD_IMPACT" )
{
level.monkey_bolt_holder = self;
}

// WW (8/20/10) - Sledgehammer fix for Issue 43492. This should stop the player from taking any damage while in laststand
if( self maps\_laststand::player_is_in_laststand() )
{
return 0;
}

if( isDefined( eAttacker ) )
{
if( isDefined( self.ignoreAttacker ) && self.ignoreAttacker == eAttacker )
{
return 0;
}

if( (isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie) || level.mutators["mutator_friendlyFire"] )
{
self.ignoreAttacker = eAttacker;
self thread remove_ignore_attacker();

if ( isdefined( eAttacker.custom_damage_func ) )
{
iDamage = eAttacker [[ eAttacker.custom_damage_func ]]( self );
}
else if ( isdefined( eAttacker.meleeDamage ) )
{
iDamage = eAttacker.meleeDamage;
}
else
{
iDamage = 50; // 45
}
}

eAttacker notify( "hit_player" );
self PlaySound( "evt_player_swiped" );
}
finalDamage = iDamage;

// claymores and freezegun shatters, like bouncing betties, harm no players
if ( sWeapon == "claymore_zm" || sWeapon == "freezegun_zm" || sWeapon == "freezegun_upgraded_zm" )
{
return 0;
}

if( sMeansOfDeath == "MOD_PROJECTILE" || sMeansOfDeath == "MOD_PROJECTILE_SPLASH" || sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" )
{
if( self.health > 75 )
{
// MM (08/10/09)
return 75;
}
}

if( iDamage {
if ( IsDefined( eAttacker ) )
{
eAttacker.sound_damage_player = self;

if( IsDefined( eAttacker.has_legs ) && !eAttacker.has_legs )
{
self maps\_zombiemode_audio::create_and_play_dialog( "general", "crawl_hit" );
}
}

// MM (08/10/09)
return finalDamage;
}
if( level.intermission )
{
level waittill( "forever" );
}

players = get_players();
count = 0;
for( i = 0; i {
if( players[i] == self || players[i].is_zombie || players[i] maps\_laststand::player_is_in_laststand() || players[i].sessionstate == "spectator" )
{
count++;
}
}
if( count {
// MM (08/10/09)
return finalDamage;
}

//if ( maps\_zombiemode_solo::solo_has_lives() )
//{
// SetDvar( "player_lastStandBleedoutTime", "3" );
//}
//else
//{
if ( players.size == 1 )
{
if ( self.lives == 0 )
{
self.intermission = true;
}
}
//}

if ( players.size > 1 || ( players.size == 1 && self.lives == 0 ) )
{
self thread maps\_laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime );
self player_fake_death();
}

if( count == players.size )
{
//if ( !maps\_zombiemode_solo::solo_has_lives() )
//{

if ( players.size == 1 )
{
if ( self.lives == 0 ) // && !self maps\_laststand::player_is_in_laststand()
{
level notify( "end_game" );
}
else
{
self thread wait_and_revive();
return finalDamage;
}
}
else
{
level notify( "end_game" );
}
//}

return 0; // MM (09/16/09) Need to return something
}
else
{
// MM (08/10/09)
return finalDamage;
}
}

wait_and_revive()
{
flag_set( "wait_and_revive" );

if ( isdefined( self.waiting_to_revive ) && self.waiting_to_revive == true )
{
return;
}

self.waiting_to_revive = true;
if ( isdefined( level.exit_level_func ) )
{
self thread [[ level.exit_level_func ]]();
}
else
{
self thread default_exit_level();
}

// wait to actually go into last stand before reviving
while ( 1 )
{
if ( self maps\_laststand::player_is_in_laststand() )
{
break;
}

wait_network_frame();
}

solo_revive_time = 10.0;

self.revive_hud setText( &"ZOMBIE_REVIVING_SOLO", self );
self maps\_laststand::revive_hud_show_n_fade( solo_revive_time );

wait( solo_revive_time );

flag_clear( "wait_and_revive" );

self maps\_laststand::auto_revive( self );
self.lives--;
self.waiting_to_revive = false;
}

//
// MUST return the value of the damage override
//
actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, modelIndex, psOffsetTime )
{
// WW (8/14/10) - define the owner of the monkey shot
if( weapon == "crossbow_explosive_upgraded_zm" && meansofdeath == "MOD_IMPACT" )
{
level.monkey_bolt_holder = self;
}

if ( isdefined( attacker.animname ) && attacker.animname == "quad_zombie" )
{
if ( isdefined( self.animname ) && self.animname == "quad_zombie" )
{
return 0;
}
}

// skip conditions
if( !isdefined( self) || !isdefined( attacker ) )
return damage;
if ( !isplayer( attacker ) && isdefined( self.non_attacker_func ) )
{
override_damage = self [[ self.non_attacker_func ]]( damage, weapon );
if ( override_damage )
return override_damage;
}
if ( !isplayer( attacker ) && !isplayer( self ) )
return damage;
if( !isdefined( damage ) || !isdefined( meansofdeath ) )
return damage;
if( meansofdeath == "" )
return damage;



// println( "*********HIT : Zombie health: "+self.health+", dam:"+damage+", weapon:"+ weapon );

old_damage = damage;
final_damage = damage;

if ( IsDefined( self.actor_damage_func ) )
{
final_damage = [[ self.actor_damage_func ]]( weapon, old_damage, attacker );
}

// debug
/#
if ( GetDvarInt( #"scr_perkdebug") )
println( "Perk/> Damage Factor: " + final_damage/old_damage + " - Pre Damage: " + old_damage + " - Post Damage: " + final_damage );
#/

if( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) )
attacker = attacker.owner;

if( !isDefined( self.damage_assists ) )
{
self.damage_assists = [];
}

if ( !isdefined( self.damage_assists[attacker.entity_num] ) )
{
self.damage_assists[attacker.entity_num] = attacker;
}

if( level.mutators[ "mutator_headshotsOnly" ] && !is_headshot( weapon, sHitLoc, meansofdeath ) )
{
return 0;
}

if( level.mutators[ "mutator_powerShot" ] )
{
final_damage = int( final_damage * 1.5 );
}

// return unchanged damage
//iPrintln( final_damage );
return int( final_damage );
}

is_headshot( sWeapon, sHitLoc, sMeansOfDeath )
{
return (sHitLoc == "head" || sHitLoc == "helmet") && sMeansOfDeath != "MOD_MELEE" && sMeansOfDeath != "MOD_BAYONET" && sMeansOfDeath != "MOD_IMPACT"; //CoD5: MGs need to cause headshots as well. && !isMG( sWeapon );
}

actor_killed_override(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime)
{
if ( game["state"] == "postgame" )
return;

if( isai(attacker) && isDefined( attacker.script_owner ) )
{
// if the person who called the dogs in switched teams make sure they don't
// get penalized for the kill
if ( attacker.script_owner.team != self.aiteam )
attacker = attacker.script_owner;
}

if( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) )
attacker = attacker.owner;

if( IsPlayer( level.monkey_bolt_holder ) && sMeansOfDeath == "MOD_GRENADE_SPLASH"
&& ( sWeapon == "crossbow_explosive_upgraded_zm" || sWeapon == "explosive_bolt_upgraded_zm" ) ) //
{
level._bolt_on_back = level._bolt_on_back + 1;
}


if ( isdefined( attacker ) && isplayer( attacker ) )
{
multiplier = 1;
if( is_headshot( sWeapon, sHitLoc, sMeansOfDeath ) )
{
multiplier = 1.5;
}

type = undefined;

//MM (3/18/10) no animname check
if ( IsDefined(self.animname) )
{
switch( self.animname )
{
case "quad_zombie":
type = "quadkill";
break;
case "ape_zombie":
type = "apekill";
break;
case "zombie":
type = "zombiekill";
break;
case "zombie_dog":
type = "dogkill";
break;
}
}
//if( isDefined( type ) )
//{
// value = maps\_zombiemode_rank::getScoreInfoValue( type );
// self process_assist( type, attacker );

// value = int( value * multiplier );
// attacker thread maps\_zombiemode_rank::giveRankXP( type, value, false, false );
//}
}

if ( IsDefined( self.actor_killed_override ) )
{
self [[ self.actor_killed_override ]]( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime );
}

}


process_assist( type, attacker )
{
if ( isDefined( self.damage_assists ) )
{
for ( j = 0; j {
player = self.damage_assists[j];

if ( !isDefined( player ) )
continue;

if ( player == attacker )
continue;

//assist_xp = maps\_zombiemode_rank::getScoreInfoValue( type + "_assist" );
//player thread maps\_zombiemode_rank::giveRankXP( type + "_assist", assist_xp );
}
self.damage_assists = undefined;
}
}


end_game()
{
level waittill ( "end_game" );

level thread maps\_zombiemode_audio::change_zombie_music( "game_over" );

//AYERS: Turn off ANY last stand audio at the end of the game
players = get_players();
for( i = 0; i {
setClientSysState( "lsm", "0", players[i] );
}

level.intermission = true;
level.zombie_vars["zombie_powerup_insta_kill_time"] = 0;
level.zombie_vars["zombie_powerup_fire_sale_time"] = 0;
level.zombie_vars["zombie_powerup_point_doubler_time"] = 0;
wait 0.1;

update_leaderboards();

game_over = [];
survived = [];

players = get_players();
for( i = 0; i {
game_over[i] = NewClientHudElem( players[i] );
game_over[i].alignX = "center";
game_over[i].alignY = "middle";
game_over[i].horzAlign = "center";
game_over[i].vertAlign = "middle";
game_over[i].y -= 130;
game_over[i].foreground = true;
game_over[i].fontScale = 3;
game_over[i].alpha = 0;
game_over[i].color = ( 1.0, 1.0, 1.0 );
game_over[i] SetText( &"ZOMBIE_GAME_OVER" );

game_over[i] FadeOverTime( 1 );
game_over[i].alpha = 1;
if ( players[i] isSplitScreen() )
{
game_over[i].y += 40;
}

survived[i] = NewClientHudElem( players[i] );
survived[i].alignX = "center";
survived[i].alignY = "middle";
survived[i].horzAlign = "center";
survived[i].vertAlign = "middle";
survived[i].y -= 100;
survived[i].foreground = true;
survived[i].fontScale = 2;
survived[i].alpha = 0;
survived[i].color = ( 1.0, 1.0, 1.0 );
if ( players[i] isSplitScreen() )
{
survived[i].y += 40;
}

//OLD COUNT METHOD
if( level.round_number {
survived[i] SetText( &"ZOMBIE_SURVIVED_ROUND" );
}
else
{
survived[i] SetText( &"ZOMBIE_SURVIVED_ROUNDS", level.round_number );
}

survived[i] FadeOverTime( 1 );
survived[i].alpha = 1;
}

players = get_players();
for (i = 0; i {
players[i] SetClientDvars( "ammoCounterHide", "1",
"miniscoreboardhide", "1" );
//players[i] maps\_zombiemode_solo::solo_destroy_lives_hud();
//players[i] maps\_zombiemode_ability::clear_hud();
}
destroy_chalk_hud();

UploadStats();

wait( 1 );

//play_sound_at_pos( "end_of_game", ( 0, 0, 0 ) );
wait( 2 );
intermission();
wait( level.zombie_vars["zombie_intermission_time"] );

level notify( "stop_intermission" );
array_thread( get_players(), ::player_exit_level );

bbPrint( "zombie_epilogs: rounds %d", level.round_number );

players = get_players();
for (i = 0; i {
survived[i] FadeOverTime( 1 );
survived[i].alpha = 0;
game_over[i] FadeOverTime( 1 );
game_over[i].alpha = 0;
}

wait( 1.5 );


/* we are not currently supporting the shared screen tech
if( IsSplitScreen() )
{
players = get_players();
for( i = 0; i {
share_screen( players[i], false );
}
}
*/

for ( j = 0; j {
player = get_players()[j];
player CameraActivate( false );

survived[j] Destroy();
game_over[j] Destroy();
}

if ( level.onlineGame || level.systemLink )
{
ExitLevel( false );
}
else
{
MissionFailed();
}

// Let's not exit the function
wait( 666 );
}

update_leaderboards()
{
if ( GetPlayers().size {
return;
}

if( level.systemLink )
{
return;
}

if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
{
return;
}

nazizombies_upload_highscore();
nazizombies_set_new_zombie_stats();
}

player_fake_death()
{
level notify ("fake_death");
self notify ("fake_death");

self TakeAllWeapons();
self AllowStand( false );
self AllowCrouch( false );
self AllowProne( true );

self.ignoreme = true;
self EnableInvulnerability();

wait( 1 );
self FreezeControls( true );
}

player_exit_level()
{
self AllowStand( true );
self AllowCrouch( false );
self AllowProne( false );

if( IsDefined( self.game_over_bg ) )
{
self.game_over_bg.foreground = true;
self.game_over_bg.sort = 100;
self.game_over_bg FadeOverTime( 1 );
self.game_over_bg.alpha = 1;
}
}

player_killed_override()
{
// BLANK
level waittill( "forever" );
}


injured_walk()
{
self.ground_ref_ent = Spawn( "script_model", ( 0, 0, 0 ) );

self.player_speed = 50;

// TODO do death countdown
self AllowSprint( false );
self AllowProne( false );
self AllowCrouch( false );
self AllowAds( false );
self AllowJump( false );

self PlayerSetGroundReferenceEnt( self.ground_ref_ent );
self thread limp();
}

limp()
{
level endon( "disconnect" );
level endon( "death" );
// TODO uncomment when/if SetBlur works again
//self thread player_random_blur();

stumble = 0;
alt = 0;

while( 1 )
{
velocity = self GetVelocity();
player_speed = abs( velocity[0] ) + abs( velocity[1] );

if( player_speed {
wait( 0.05 );
continue;
}

speed_multiplier = player_speed / self.player_speed;

p = RandomFloatRange( 3, 5 );
if( RandomInt( 100 ) {
p *= 3;
}
r = RandomFloatRange( 3, 7 );
y = RandomFloatRange( -8, -2 );

stumble_angles = ( p, y, r );
stumble_angles = vector_scale( stumble_angles, speed_multiplier );

stumble_time = RandomFloatRange( .35, .45 );
recover_time = RandomFloatRange( .65, .8 );

stumble++;
if( speed_multiplier > 1.3 )
{
stumble++;
}

self thread stumble( stumble_angles, stumble_time, recover_time );

level waittill( "recovered" );
}
}

stumble( stumble_angles, stumble_time, recover_time, no_notify )
{
stumble_angles = self adjust_angles_to_player( stumble_angles );

self.ground_ref_ent RotateTo( stumble_angles, stumble_time, ( stumble_time/4*3 ), ( stumble_time/4 ) );
self.ground_ref_ent waittill( "rotatedone" );

base_angles = ( RandomFloat( 4 ) - 4, RandomFloat( 5 ), 0 );
base_angles = self adjust_angles_to_player( base_angles );

self.ground_ref_ent RotateTo( base_angles, recover_time, 0, ( recover_time / 2 ) );
self.ground_ref_ent waittill( "rotatedone" );

if( !IsDefined( no_notify ) )
{
level notify( "recovered" );
}
}

adjust_angles_to_player( stumble_angles )
{
pa = stumble_angles[0];
ra = stumble_angles[2];

rv = AnglesToRight( self.angles );
fv = AnglesToForward( self.angles );

rva = ( rv[0], 0, rv[1]*-1 );
fva = ( fv[0], 0, fv[1]*-1 );
angles = vector_scale( rva, pa );
angles = angles + vector_scale( fva, ra );
return angles +( 0, stumble_angles[1], 0 );
}

coop_player_spawn_placement()
{
structs = getstructarray( "initial_spawn_points", "targetname" );

temp_ent = Spawn( "script_model", (0,0,0) );
for( i = 0; i {
temp_ent.origin = structs[i].origin;
temp_ent placeSpawnpoint();
structs[i].origin = temp_ent.origin;
}
temp_ent Delete();

flag_wait( "all_players_connected" );

//chrisp - adding support for overriding the default spawning method

players = get_players();

for( i = 0; i {
players[i] setorigin( structs[i].origin );
players[i] setplayerangles( structs[i].angles );
players[i].spectator_respawn = structs[i];
}
}


player_zombie_breadcrumb()
{
self endon( "disconnect" );
self endon( "spawned_spectator" );
level endon( "intermission" );

self.zombie_breadcrumbs = [];
self.zombie_breadcrumb_distance = 24 * 24; // min dist (squared) the player must move to drop a crumb
self.zombie_breadcrumb_area_num = 3; // the number of "rings" the area breadcrumbs use
self.zombie_breadcrumb_area_distance = 16; // the distance between each "ring" of the area breadcrumbs

self store_crumb( self.origin );
last_crumb = self.origin;

self thread debug_breadcrumbs();

while( 1 )
{
wait_time = 0.1;

/#
if( self isnotarget() )
{
wait( wait_time );
continue;
}
#/

//For cloaking ability
//if( self.ignoreme )
//{
// wait( wait_time );
// continue;
//}


store_crumb = true;
airborne = false;
crumb = self.origin;

//TODO TEMP SCRIPT for vehicle testing Delete/comment when done
if ( !self IsOnGround() && self isinvehicle() )
{
trace = bullettrace( self.origin + (0,0,10), self.origin, false, undefined );
crumb = trace["position"];
}

//TODO TEMP DISABLE for vehicle testing. Uncomment when reverting
// if ( !self IsOnGround() )
// {
// airborne = true;
// store_crumb = false;
// wait_time = 0.05;
// }
//
if( !airborne && DistanceSquared( crumb, last_crumb ) {
store_crumb = false;
}

if ( airborne && self IsOnGround() )
{
// player was airborne, store crumb now that he's on the ground
store_crumb = true;
airborne = false;
}

if( isDefined( level.custom_breadcrumb_store_func ) )
{
store_crumb = self [[ level.custom_breadcrumb_store_func ]]( store_crumb );
}

if( isDefined( level.custom_airborne_func ) )
{
airborne = self [[ level.custom_airborne_func ]]( airborne );
}

if( store_crumb )
{
debug_print( "Player is storing breadcrumb " + crumb );

if( IsDefined(self.node) )
{
debug_print( "has closest node " );
}

last_crumb = crumb;
self store_crumb( crumb );
}

wait( wait_time );
}
}


store_crumb( origin )
{
offsets = [];
height_offset = 32;

index = 0;
for( j = 1; j {
offset = ( j * self.zombie_breadcrumb_area_distance );

offsets[0] = ( origin[0] - offset, origin[1], origin[2] );
offsets[1] = ( origin[0] + offset, origin[1], origin[2] );
offsets[2] = ( origin[0], origin[1] - offset, origin[2] );
offsets[3] = ( origin[0], origin[1] + offset, origin[2] );

offsets[4] = ( origin[0] - offset, origin[1], origin[2] + height_offset );
offsets[5] = ( origin[0] + offset, origin[1], origin[2] + height_offset );
offsets[6] = ( origin[0], origin[1] - offset, origin[2] + height_offset );
offsets[7] = ( origin[0], origin[1] + offset, origin[2] + height_offset );

for ( i = 0; i {
self.zombie_breadcrumbs[index] = offsets[i];
index++;
}
}
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////LEADERBOARD CODE///////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//CODER MOD: TOMMY K
nazizombies_upload_highscore()
{
// Nazi Zombie Leaderboards
// nazi_zombie_prototype_waves = 13
// nazi_zombie_prototype_points = 14

// this has gotta be the dumbest way of doing this, but at 1:33am in the morning my brain is fried!
playersRank = 1;
if( level.players_playing == 1 )
playersRank = 4;
else if( level.players_playing == 2 )
playersRank = 3;
else if( level.players_playing == 3 )
playersRank = 2;

map_name = GetDvar( #"mapname" );

if ( !isZombieLeaderboardAvailable( map_name, "waves" ) || !isZombieLeaderboardAvailable( map_name, "points" ) )
return;

players = get_players();
for( i = 0; i {
pre_highest_wave = players[i] playerZombieStatGet( map_name, "highestwave" );
pre_time_in_wave = players[i] playerZombieStatGet( map_name, "timeinwave" );

new_highest_wave = level.round_number + "" + playersRank;
new_highest_wave = int( new_highest_wave );

if( new_highest_wave >= pre_highest_wave )
{
if( players[i].zombification_time == 0 )
{
players[i].zombification_time = GetTime();
}

player_survival_time = players[i].zombification_time - level.round_start_time;
player_survival_time = int( player_survival_time/1000 );

if( new_highest_wave > pre_highest_wave || player_survival_time > pre_time_in_wave )
{
rankNumber = makeRankNumber( level.round_number, playersRank, player_survival_time );

leaderboard_number = getZombieLeaderboardNumber( map_name, "waves" );

players[i] UploadScore( leaderboard_number, int(rankNumber), level.round_number, player_survival_time, level.players_playing );
//players[i] UploadScore( leaderboard_number, int(rankNumber), level.round_number );

players[i] playerZombieStatSet( map_name, "highestwave", new_highest_wave );
players[i] playerZombieStatSet( map_name, "timeinwave", player_survival_time );
}
}

pre_total_points = players[i] playerZombieStatGet( map_name, "totalpoints" );
if( players[i].score_total > pre_total_points )
{
leaderboard_number = getZombieLeaderboardNumber( map_name, "points" );

players[i] UploadScore( leaderboard_number, players[i].score_total, players[i].kills, level.players_playing );

players[i] playerZombieStatSet( map_name, "totalpoints", players[i].score_total );
}
}
}

isZombieLeaderboardAvailable( map, type )
{
if ( !isDefined( level.zombieLeaderboardNumber[map] ) )
return 0;

if ( !isDefined( level.zombieLeaderboardNumber[map][type] ) )
return 0;

return 1;
}

getZombieLeaderboardNumber( map, type )
{
if ( !isDefined( level.zombieLeaderboardNumber[map][type] ) )
assertMsg( "Unknown leaderboard number for map " + map + "and type " + type );

return level.zombieLeaderboardNumber[map][type];
}

getZombieStatVariable( map, variable )
{
if ( !isDefined( level.zombieLeaderboardStatVariable[map][variable] ) )
assertMsg( "Unknown stat variable " + variable + " for map " + map );

return level.zombieLeaderboardStatVariable[map][variable];
}

playerZombieStatGet( map, variable )
{
stat_variable = getZombieStatVariable( map, variable );
result = self zombieStatGet( stat_variable );

return result;
}

playerZombieStatSet( map, variable, value )
{
stat_variable = getZombieStatVariable( map, variable );
self zombieStatSet( stat_variable, value );
}

nazizombies_set_new_zombie_stats()
{
players = get_players();
for( i = 0; i {
//grab stat and add final totals
total_kills = players[i] zombieStatGet( "zombie_kills" ) + players[i].stats["kills"];
total_points = players[i] zombieStatGet( "zombie_points" ) + players[i].stats["score"];
total_rounds = players[i] zombieStatGet( "zombie_rounds" ) + (level.round_number - 1); // rounds survived
total_downs = players[i] zombieStatGet( "zombie_downs" ) + players[i].stats["downs"];
total_revives = players[i] zombieStatGet( "zombie_revives" ) + players[i].stats["revives"];
total_perks = players[i] zombieStatGet( "zombie_perks_consumed" ) + players[i].stats["perks"];
total_headshots = players[i] zombieStatGet( "zombie_heashots" ) + players[i].stats["headshots"];
total_zombie_gibs = players[i] zombieStatGet( "zombie_gibs" ) + players[i].stats["zombie_gibs"];

//set zombie stats
players[i] zombieStatSet( "zombie_kills", total_kills );
players[i] zombieStatSet( "zombie_points", total_points );
players[i] zombieStatSet( "zombie_rounds", total_rounds );
players[i] zombieStatSet( "zombie_downs", total_downs );
players[i] zombieStatSet( "zombie_revives", total_revives );
players[i] zombieStatSet( "zombie_perks_consumed", total_perks );
players[i] zombieStatSet( "zombie_heashots", total_headshots );
players[i] zombieStatSet( "zombie_gibs", total_zombie_gibs );
}
}

makeRankNumber( wave, players, time )
{
if( time > 86400 )
time = 86400; // cap it at like 1 day, need to cap cause you know some muppet is gonna end up trying it

//pad out time
padding = "";
if ( 10 > time )
padding += "0000";
else if( 100 > time )
padding += "000";
else if( 1000 > time )
padding += "00";
else if( 10000 > time )
padding += "0";

rank = wave + "" + players + padding + time;

return rank;
}


//CODER MOD: TOMMY K
/*
=============
zombieStatGet

Returns the value of the named stat
=============
*/
zombieStatGet( dataName )
{
if( level.systemLink )
{
return;
}
if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
{
return;
}

return ( self getdstat( "PlayerStatsList", dataName ) );
}

//CODER MOD: TOMMY K
/*
=============
zombieStatSet

Sets the value of the named stat
=============
*/
zombieStatSet( dataName, value )
{
if( level.systemLink )
{
return;
}
if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
{
return;
}

self setdstat( "PlayerStatsList", dataName, value );
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//
// INTERMISSION =========================================================== //
//

intermission()
{
level.intermission = true;
level notify( "intermission" );

players = get_players();
for( i = 0; i {
setclientsysstate( "levelNotify", "zi", players[i] ); // Tell clientscripts we're in zombie intermission

players[i] SetClientDvars( "cg_thirdPerson", "0",
"cg_fov", "65" );

players[i].health = 100; // This is needed so the player view doesn't get stuck
players[i] thread [[level.custom_intermission]]();
}

wait( 0.25 );

// Delay the last stand monitor so we are 100% sure the zombie intermission ("zi") is set on the cients
players = get_players();
for( i = 0; i {
setClientSysState( "lsm", "0", players[i] );
}

visionset = "zombie";
if( IsDefined( level.zombie_vars["intermission_visionset"] ) )
{
visionset = level.zombie_vars["intermission_visionset"];
}

level thread maps\_utility::set_all_players_visionset( visionset, 2 );
level thread zombie_game_over_death();
}

zombie_game_over_death()
{
// Kill remaining zombies, in style!
zombies = GetAiArray( "axis" );
for( i = 0; i {
if( !IsAlive( zombies[i] ) )
{
continue;
}

zombies[i] SetGoalPos( zombies[i].origin );
}

for( i = 0; i {
if( !IsAlive( zombies[i] ) )
{
continue;
}

wait( 0.5 + RandomFloat( 2 ) );

zombies[i] maps\_zombiemode_spawner::zombie_head_gib();
zombies[i] DoDamage( zombies[i].health + 666, zombies[i].origin );
}
}

player_intermission()
{
self closeMenu();
self closeInGameMenu();

level endon( "stop_intermission" );
self endon("disconnect");
self endon("death");
self notify( "_zombie_game_over" ); // ww: notify so hud elements know when to leave

//Show total gained point for end scoreboard and lobby
self.score = self.score_total;

self.sessionstate = "intermission";
self.spectatorclient = -1;
self.killcamentity = -1;
self.archivetime = 0;
self.psoffsettime = 0;
self.friendlydamage = undefined;

points = getstructarray( "intermission", "targetname" );

if( !IsDefined( points ) || points.size == 0 )
{
points = getentarray( "info_intermission", "classname" );
if( points.size {
println( "NO info_intermission POINTS IN MAP" );
return;
}
}

self.game_over_bg = NewClientHudelem( self );
self.game_over_bg.horzAlign = "fullscreen";
self.game_over_bg.vertAlign = "fullscreen";
self.game_over_bg SetShader( "black", 640, 480 );
self.game_over_bg.alpha = 1;

org = undefined;
while( 1 )
{
points = array_randomize( points );
for( i = 0; i {
point = points[i];
// Only spawn once if we are using 'moving' org
// If only using info_intermissions, this will respawn after 5 seconds.
if( !IsDefined( org ) )
{
self Spawn( point.origin, point.angles );
}

// Only used with STRUCTS
if( IsDefined( points[i].target ) )
{
if( !IsDefined( org ) )
{
org = Spawn( "script_model", self.origin + ( 0, 0, -60 ) );
org SetModel("tag_origin");
}

// self LinkTo( org, "", ( 0, 0, -60 ), ( 0, 0, 0 ) );
// self SetPlayerAngles( points[i].angles );
org.origin = points[i].origin;
org.angles = points[i].angles;


for ( j = 0; j {
player = get_players()[j];
player CameraSetPosition( org );
player CameraSetLookAt();
player CameraActivate( true );
}

speed = 20;
if( IsDefined( points[i].speed ) )
{
speed = points[i].speed;
}

target_point = getstruct( points[i].target, "targetname" );
dist = Distance( points[i].origin, target_point.origin );
time = dist / speed;

q_time = time * 0.25;
if( q_time > 1 )
{
q_time = 1;
}

self.game_over_bg FadeOverTime( q_time );
self.game_over_bg.alpha = 0;

org MoveTo( target_point.origin, time, q_time, q_time );
org RotateTo( target_point.angles, time, q_time, q_time );
wait( time - q_time );

self.game_over_bg FadeOverTime( q_time );
self.game_over_bg.alpha = 1;

wait( q_time );
}
else
{
self.game_over_bg FadeOverTime( 1 );
self.game_over_bg.alpha = 0;

wait( 5 );

self.game_over_bg thread fade_up_over_time(1);

//wait( 1 );
}
}
}
}

fade_up_over_time(t)
{
self FadeOverTime( t );
self.alpha = 1;
}

prevent_near_origin()
{
while (1)
{
players = get_players();

for (i = 0; i {
for (q = 0; q {
if (players[i] != players[q])
{
if (check_to_kill_near_origin(players[i], players[q]))
{
p1_org = players[i].origin;
p2_org = players[q].origin;

wait 5;

if (check_to_kill_near_origin(players[i], players[q]))
{
if ( (distance(players[i].origin, p1_org) {
setsaveddvar("player_deathInvulnerableTime", 0);
players[i] DoDamage( players[i].health + 1000, players[i].origin, undefined, undefined, "riflebullet" );
setsaveddvar("player_deathInvulnerableTime", level.startInvulnerableTime);
}
}
}
}
}
}

wait 0.2;
}
}

check_to_kill_near_origin(player1, player2)
{
if (!isdefined(player1) || !isdefined(player2))
{
return false;
}

if (distance(player1.origin, player2.origin) > 12)
{
return false;
}

if ( player1 maps\_laststand::player_is_in_laststand() || player2 maps\_laststand::player_is_in_laststand() )
{
return false;
}

if (!isalive(player1) || !isalive(player2))
{
return false;
}

return true;
}


//
crawler_round_tracker()
{
level.crawler_round_count = 1;

level.next_crawler_round = 4;

sav_func = level.round_spawn_func;
while ( 1 )
{
level waittill ( "between_round_over" );

/#
if( GetDvarInt( #"force_crawlers" ) > 0 )
{
next_crawler_round = level.round_number;
}
#/

if ( level.round_number == level.next_crawler_round )
{
sav_func = level.round_spawn_func;
crawler_round_start();
level.round_spawn_func = ::round_spawning;

if ( IsDefined( level.next_dog_round ) )
{
level.next_crawler_round = level.next_dog_round + randomintrange( 2, 3 );
}
else
{
level.next_crawler_round = randomintrange( 4, 6 );
}
/#
get_players()[0] iprintln( "Next crawler round: " + level.next_crawler_round );
#/
}
else if ( flag( "crawler_round" ) )
{
crawler_round_stop();

// Don't trample over the round_spawn_func setting
if ( IsDefined( level.next_dog_round ) &&
level.next_dog_round == level.round_number )
{
level.round_spawn_func = sav_func;
}

level.crawler_round_count += 1;
}
}
}


crawler_round_start()
{
flag_set( "crawler_round" );
if(!IsDefined (level.crawlerround_nomusic))
{
level.crawlerround_nomusic = 0;
}
level.crawlerround_nomusic = 1;
level notify( "crawler_round_starting" );
clientnotify( "crawler_start" );
}


crawler_round_stop()
{
flag_clear( "crawler_round" );

if(!IsDefined (level.crawlerround_nomusic))
{
level.crawlerround_nomusic = 0;
}
level.crawlerround_nomusic = 0;
level notify( "crawler_round_ending" );
clientnotify( "crawler_stop" );
}

default_exit_level()
{
spawn_locs = getstructarray("player_respawn_point", "targetname");
index = -1;

for( i = 0; i {
dist_squared = DistanceSquared( spawn_locs[i].origin, self.origin );
if( dist_squared > ( 400 * 400 ) && dist_squared {
index = i;
break;
}
}

if ( index == -1 )
{
for( i = 0; i {
dist_squared = DistanceSquared( spawn_locs[i].origin, self.origin );
if( dist_squared > ( 400 * 400 ) )
{
index = i;
break;
}
}
}

if ( index == -1 )
{
spawn_locs = getstructarray("initial_spawn_points", "targetname");
index = 0;
}

exit_loc = spawn_locs[index].origin;

poi = Spawn( "script_origin", exit_loc );
poi create_zombie_point_of_interest( undefined, 25, 0, false );
poi thread create_zombie_point_of_interest_attractor_positions( 4, 45 );
poi activate_zombie_point_of_interest();

while ( 1 )
{
if ( !flag( "wait_and_revive" ) )
{
break;
}
wait_network_frame();
}

poi deactivate_zombie_point_of_interest();
poi delete();
}

play_level_start_vox_delayed()
{
wait(5);
players = getplayers();
num = RandomIntRange( 0, players.size );
players[num] maps\_zombiemode_audio::create_and_play_dialog( "general", "intro" );
}

Link to comment

Zombiemode_aidogs

#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include maps\_zombiemode_net;
#include maps\_music;

init()
{
level.dogs_enabled = true;
level.dog_rounds_enabled = false;
level.dog_round_count = 1;

level.enemy_dog_spawns = [];
level.enemy_dog_locations = [];
flag_init( "dog_round" );
flag_init( "dog_clips" );

PreCacheRumble( "explosion_generic" );

if ( GetDvar( #"zombie_dog_animset" ) == "" )
{
SetDvar( "zombie_dog_animset", "zombie" );
}

if ( GetDvar( #"scr_dog_health_walk_multiplier" ) == "" )
{
SetDvar( "scr_dog_health_walk_multiplier", "4.0" );
}

if ( GetDvar( #"scr_dog_run_distance" ) == "" )
{
SetDvar( "scr_dog_run_distance", "500" );
}

level.melee_range_sav = GetDvar( #"ai_meleeRange" );
level.melee_height_sav = GetDvar( #"ai_meleeWidth" );
level.melee_width_sav = GetDvar( #"ai_meleeHeight" );

// this gets rounded down to 40 damage after the dvar 'player_meleeDamageMultiplier' runs its calculation
SetSavedDvar( "dog_MeleeDamage", "100" );
set_zombie_var( "dog_fire_trail_percent", 50 );

level._effect[ "lightning_dog_spawn" ] = Loadfx( "maps/zombie/fx_zombie_dog_lightning_buildup" );
level._effect[ "dog_eye_glow" ] = Loadfx( "maps/zombie/fx_zombie_dog_eyes" );
level._effect[ "dog_gib" ] = Loadfx( "maps/zombie/fx_zombie_dog_explosion" );
level._effect[ "dog_trail_fire" ] = Loadfx( "maps/zombie/fx_zombie_dog_fire_trail" );
level._effect[ "dog_trail_ash" ] = Loadfx( "maps/zombie/fx_zombie_dog_ash_trail" );

animscripts\zombie_dog_init::initDogAnimations();

// Init dog targets - mainly for testing purposes.
// If you spawn a dog without having a dog round, you'll get SREs on hunted_by.
dog_spawner_init();

level thread dog_clip_monitor();
}


//
// If you want to enable dog rounds, then call this.
// Specify an override func if needed.
enable_dog_rounds()
{
level.dog_rounds_enabled = true;

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()
{
dogs = getEntArray( "zombie_dog_spawner", "script_noteworthy" );
later_dogs = getentarray("later_round_dog_spawners", "script_noteworthy" );
dogs = array_combine( dogs, later_dogs );

if( dogs.size == 0 )
{
return;
}

for( i = 0; i {
if( maps\_zombiemode_spawner::is_spawner_targeted_by_blocker( dogs[i] ) )
{
dogs[i].is_enabled = false;
}
else
{
dogs[i].is_enabled = true;
}
}

assert( dogs.size > 0 );
level.dog_health = 100;

array_thread( dogs, ::add_spawn_function, ::dog_init );

//level.enemy_dog_spawns = getnodearray( "zombie_spawner_dog_init", "script_noteworthy" );
level.enemy_dog_spawns = getEntArray( "zombie_spawner_dog_init", "targetname" );
}


dog_round_spawning()
{
level endon( "intermission" );

level.dog_targets = getplayers();
for( i = 0 ; i {
level.dog_targets[i].hunted_by = 0;
}


//assert( level.enemy_dog_spawns.size > 0 );

/#
level endon( "kill_round" );

if ( GetDvarInt( #"zombie_cheat" ) == 2 || GetDvarInt( #"zombie_cheat" ) >= 4 )
{
return;
}
#/

if( level.intermission )
{
return;
}

level.dog_intermission = true;
level thread dog_round_aftermath();
players = get_players();
array_thread( players, ::play_dog_round );
wait(7);

if( level.dog_round_count {
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( count {
num_player_valid = get_number_of_valid_players();

while( get_enemy_count() >= num_player_valid * 2 )
{
wait( 2 );
num_player_valid = get_number_of_valid_players();
}

//update the player array.
players = get_players();
favorite_enemy = get_favorite_enemy();

if ( IsDefined( level.dog_spawn_func ) )
{
spawn_loc = [[level.dog_spawn_func]]( level.enemy_dog_spawns, favorite_enemy );

ai = spawn_zombie( level.enemy_dog_spawns[0] );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_loc thread dog_spawn_fx( ai, spawn_loc );
level.zombie_total--;
count++;
}
}
else
{
// Old method
spawn_point = dog_spawn_sumpf_logic( level.enemy_dog_spawns, favorite_enemy );
ai = spawn_zombie( spawn_point );

if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_point thread dog_spawn_fx( ai );
level.zombie_total--;
count++;

}
}


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" );

level thread maps\_zombiemode_audio::change_zombie_music( "dog_end" );

power_up_origin = level.last_dog_origin;

if( IsDefined( power_up_origin ) )
{
level thread maps\_zombiemode_powerups::specific_powerup_drop( "full_ammo", power_up_origin );
}

wait(2);
clientnotify( "dog_stop" );
wait(6);
level.dog_intermission = false;

//level thread dog_round_aftermath();

}


//
// In Sumpf, the dog spawner targets a struct to spawn from.
// In Factory, there's a single spawner and the struct is passed in as the second argument.
dog_spawn_fx( ai, ent )
{
if ( !IsDefined(ent) )
{
ent = GetStruct( self.target, "targetname" );
}

if ( isdefined( ent ) )
{
Playfx( level._effect["lightning_dog_spawn"], ent.origin );
playsoundatposition( "zmb_hellhound_prespawn", ent.origin );
wait( 1.5 );
playsoundatposition( "zmb_hellhound_bolt", ent.origin );

Earthquake( 0.5, 0.75, ent.origin, 1000);
PlayRumbleOnPosition("explosion_generic", ent.origin);
playsoundatposition( "zmb_hellhound_spawn", ent.origin );

// face the enemy
angle = VectorToAngles( ai.favoriteenemy.origin - ent.origin );
angles = ( ai.angles[0], angle[1], ai.angles[2] );
ai ForceTeleport( ent.origin, angles );
}

assertex( IsDefined( ai ), "Ent isn't defined." );
assertex( IsAlive( ai ), "Ent is dead." );
assertex( ai.isdog, "Ent isn't a dog;" );
assertex( is_magic_bullet_shield_enabled( ai ), "Ent doesn't have a magic bullet shield." );

ai zombie_setup_attack_properties_dog();
ai stop_magic_bullet_shield();

wait( 0.1 ); // dog should come out running after this wait
ai show();
ai.ignoreme = false; // don't let attack dogs give chase until the wolf is visible
ai notify( "visible" );
}


//
// Dog spawning logic for swamp
dog_spawn_sumpf_logic( dog_array, favorite_enemy)
{

assertex( dog_array.size > 0, "Dog Spawner array is empty." );
dog_array = array_randomize( dog_array );
for( i = 0; i {
if( IsDefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_array[i] )
{
continue;
}

if( DistanceSquared( dog_array[i].origin, favorite_enemy.origin ) > ( 400 * 400 ) && DistanceSquared( dog_array[i].origin, favorite_enemy.origin ) {

if(distanceSquared( ( 0, 0, dog_array[i].origin[2] ), ( 0, 0, favorite_enemy.origin[2] ) ) > 100 * 100 )
{
continue;
}
else
{
level.old_dog_spawn = dog_array[i];
return dog_array[i];
}

}

}

return dog_array[0];

}


//
// Dog spawning logic for Factory.
// Makes use of the _zombiemode_zone_manager and specially named structs for each zone to
// indicate dog spawn locations instead of constantly using ents.
//
dog_spawn_factory_logic( dog_array, favorite_enemy)
{
dog_locs = array_randomize( level.enemy_dog_locations );
//assertex( dog_locs.size > 0, "Dog Spawner locs array is empty." );

for( i = 0; i {
if( IsDefined( level.old_dog_spawn ) && level.old_dog_spawn == dog_locs[i] )
{
continue;
}

dist_squared = DistanceSquared( dog_locs[i].origin, favorite_enemy.origin );
if( dist_squared > ( 400 * 400 ) && dist_squared {
level.old_dog_spawn = dog_locs[i];
return dog_locs[i];
}
}

return dog_locs[0];
}


get_favorite_enemy()
{
dog_targets = getplayers();
least_hunted = dog_targets[0];
for( i = 0; i {
if ( !IsDefined( dog_targets[i].hunted_by ) )
{
dog_targets[i].hunted_by = 0;
}

if( !is_player_valid( dog_targets[i] ) )
{
continue;
}

if( !is_player_valid( least_hunted ) )
{
least_hunted = dog_targets[i];
}

if( dog_targets[i].hunted_by {
least_hunted = dog_targets[i];
}

}

least_hunted.hunted_by += 1;

return least_hunted;


}


dog_health_increase()
{
players = getplayers();

if( level.dog_round_count == 1 )
{
level.dog_health = 400;
}
else if( level.dog_round_count == 2 )
{
level.dog_health = 900;
}
else if( level.dog_round_count == 3 )
{
level.dog_health = 1300;
}
else if( level.dog_round_count == 4 )
{
level.dog_health = 1600;
}

if( level.dog_health > 1600 )
{
level.dog_health = 1600;
}
}


dog_round_tracker()
{
level.dog_round_count = 1;

// PI_CHANGE_BEGIN - JMA - making dog rounds random between round 5 thru 7
// NOTE: RandomIntRange returns a random integer r, where min level.next_dog_round = randomintrange( 5, 8 );
// PI_CHANGE_END

old_spawn_func = level.round_spawn_func;
old_wait_func = level.round_wait_func;

while ( 1 )
{
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 = true;
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 );
/#
get_players()[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 = false;
level.dog_round_count += 1;
}
}
}


dog_round_start()
{
flag_set( "dog_round" );
flag_set( "dog_clips" );

level thread maps\_zombiemode_audio::change_zombie_music( "dog_start" );

if(!IsDefined (level.doground_nomusic))
{
level.doground_nomusic = 0;
}
level.doground_nomusic = 1;
level notify( "dog_round_starting" );
clientnotify( "dog_start" );

level.melee_range_sav = 100;
level.melee_height_sav = 0;
level.melee_width_sav = 0;

SetDvar( "ai_meleeRange", "100" );
SetDvar( "ai_meleeWidth", "0" );
SetDvar( "ai_meleeHeight", "0" );
}


dog_round_stop()
{
flag_clear( "dog_round" );
flag_clear( "dog_clips" );

//level thread maps\_zombiemode_audio::change_zombie_music( "dog_end" );

//play_sound_2D( "mus_zombie_dog_end" );
if(!IsDefined (level.doground_nomusic))
{
level.doground_nomusic = 0;
}
level.doground_nomusic = 0;
level notify( "dog_round_ending" );
clientnotify( "dog_stop" );

SetDvar( "ai_meleeRange", level.melee_range_sav );
SetDvar( "ai_meleeWidth", level.melee_width_sav );
SetDvar( "ai_meleeHeight", level.melee_height_sav );
}


play_dog_round()
{
self playlocalsound( "zmb_dog_round_start" );
variation_count =5;

wait (1);
play_sound_2D( "zmb_vox_ann_dogstart" );

wait(3.5);

players = getplayers();
num = randomintrange(0,players.size);
players[num] maps\_zombiemode_audio::create_and_play_dialog( "general", "dog_spawn" );
}


dog_init()
{
self.targetname = "zombie_dog";
self.script_noteworthy = undefined;
self.animname = "zombie_dog";
self.ignoreall = true;
self.ignoreme = true; // don't let attack dogs give chase until the wolf is visible
self.allowdeath = true; // allows death during animscripted calls
self.allowpain = false;
self.force_gib = true; // needed to make sure this guy does gibs
self.is_zombie = true; // needed for melee.gsc in the animscripts
self.has_legs = true; // Sumeet - This tells the zombie that he is allowed to stand anymore or not, gibbing can take
// out both legs and then the only allowed stance should be prone.
self.gibbed = false;
self.head_gibbed = false;
if ( !isDefined(level.zombietron) )
{
self.default_goalheight = 40;
}
animscripts\zombie_dog_init::change_anim_set( GetDvar( #"zombie_dog_animset" ) );

// self.disableArrivals = true;
// self.disableExits = true;
self.grenadeawareness = 0;
self.badplaceawareness = 0;

self.ignoreSuppression = true;
self.suppressionThreshold = 1;
self.noDodgeMove = true;
self.dontShootWhileMoving = true;
self.pathenemylookahead = 0;

self.badplaceawareness = 0;
self.chatInitialized = false;

self setTeamForEntity( "axis" );

health_multiplier = 1.0;
if ( GetDvar( #"scr_dog_health_walk_multiplier" ) != "" )
{
health_multiplier = GetDvarFloat( #"scr_dog_health_walk_multiplier" );
}

self.maxhealth = int( level.dog_health * health_multiplier );
self.health = int( level.dog_health * health_multiplier );

self.freezegun_damage = 0;

self.zombie_move_speed = "sprint";

self thread dog_run_think();
self thread dog_stalk_audio();

self thread maps\_zombiemode::round_spawn_failsafe();
self hide();
self thread magic_bullet_shield();
self dog_fx_eye_glow();
self dog_fx_trail();

self thread dog_death();

self.a.disablePain = true;
self disable_react(); // SUMEET - zombies dont use react feature.
self ClearEnemy();
self ClearGoalVolume();

self.flame_damage_time = 0;
self.meleeDamage = 40;

self.thundergun_disintegrate_func = ::dog_thundergun_disintegrate;
self.thundergun_knockdown_func = ::dog_thundergun_knockdown;

self maps\_zombiemode_spawner::zombie_history( "zombie_dog_spawn_init -> Spawned = " + self.origin );
}


dog_fx_eye_glow()
{
self.fx_dog_eye = Spawn( "script_model", self GetTagOrigin( "J_EyeBall_LE" ) );
assert( IsDefined( self.fx_dog_eye ) );

self.fx_dog_eye.angles = self GetTagAngles( "J_EyeBall_LE" );
self.fx_dog_eye SetModel( "tag_origin" );
self.fx_dog_eye LinkTo( self, "J_EyeBall_LE" );
}


dog_fx_trail()
{
if( !is_mature() || randomint( 100 ) > level.zombie_vars["dog_fire_trail_percent"] )
{
self.fx_dog_trail_type = level._effect[ "dog_trail_ash" ];
self.fx_dog_trail_sound = "zmb_hellhound_loop_breath";
}
else
{
//fire dogs will explode during death
self.a.nodeath = true;

self.fx_dog_trail_type = level._effect[ "dog_trail_fire" ];
self.fx_dog_trail_sound = "zmb_hellhound_loop_fire";
}

self.fx_dog_trail = Spawn( "script_model", self GetTagOrigin( "tag_origin" ) );
assert( IsDefined( self.fx_dog_trail ) );

self.fx_dog_trail.angles = self GetTagAngles( "tag_origin" );
self.fx_dog_trail SetModel( "tag_origin" );
self.fx_dog_trail LinkTo( self, "tag_origin" );
}

dog_death()
{
self waittill( "death" );

if( get_enemy_count() == 0 && level.zombie_total == 0 )
{

level.last_dog_origin = self.origin;
level notify( "last_dog_down" );

}

// score
if( IsPlayer( self.attacker ) )
{
event = "death";
if ( issubstr( self.damageweapon, "knife_ballistic_" ) )
{
event = "ballistic_knife_death";
}

self.attacker maps\_zombiemode_score::player_add_points( event, self.damagemod, self.damagelocation, true );

if( RandomIntRange(0,100) >= 80 )
{
self.attacker maps\_zombiemode_audio::create_and_play_dialog( "kill", "hellhound" );
}
}

// switch to inflictor when SP DoDamage supports it
if( isdefined( self.attacker ) && isai( self.attacker ) )
{
self.attacker notify( "killed", self );
}

// sound
self stoploopsound();

// fx
assert( IsDefined( self.fx_dog_eye ) );
self.fx_dog_eye delete();

assert( IsDefined( self.fx_dog_trail ) );
self.fx_dog_trail delete();

if ( IsDefined( self.a.nodeath ) )
{
level thread dog_explode_fx( self.origin );
self delete();
}
else
{
self PlaySound( "zmb_hellhound_vocals_death" );
}
}


dog_explode_fx( origin )
{
fx = network_safe_spawn( "dog_death_fx", 2, "script_model", origin );
assert( IsDefined( fx ) );

fx SetModel( "tag_origin" );
PlayFxOnTag( level._effect["dog_gib"], fx, "tag_origin" );
fx playsound( "zmb_hellhound_explode" );

wait( 5 );
fx delete();
}


// this is where zombies go into attack mode, and need different attributes set up
zombie_setup_attack_properties_dog()
{
self maps\_zombiemode_spawner::zombie_history( "zombie_setup_attack_properties()" );

self thread dog_behind_audio();

// allows zombie to attack again
self.ignoreall = false;

self.pathEnemyFightDist = 64;
self.meleeAttackDist = 64;

// turn off transition anims
self.disableArrivals = true;
self.disableExits = true;

}


//COLLIN'S Audio Scripts
stop_dog_sound_on_death()
{
self waittill("death");
self stopsounds();
}

dog_behind_audio()
{
self thread stop_dog_sound_on_death();

self endon("death");
self waittill_any( "dog_running", "dog_combat" );

self PlaySound( "zmb_hellhound_vocals_close", "sounddone" );
self waittill( "sounddone" );

while(1)
{
players = get_players();
for(i=0;i {
dogAngle = AngleClamp180( vectorToAngles( self.origin - players[i].origin )[1] - players[i].angles[1] );

if(isAlive(players[i]) && !isDefined(players[i].revivetrigger))
{
if ((abs(dogAngle) > 90) && distance2d(self.origin,players[i].origin) > 100)
{
self playsound( "zmb_hellhound_vocals_close", "sounddone" );
self waittill( "sounddone" );
}
}
}

wait(.75);
}
}


//
// Keeps dog_clips up if there is a dog running around in the level.
dog_clip_monitor()
{
clips_on = false;
level.dog_clips = GetEntArray( "dog_clips", "targetname" );
while (1)
{
for ( i=0; i {
level.dog_clips[i] trigger_off();
level.dog_clips[i] ConnectPaths();
}
flag_wait( "dog_clips" );

for ( i=0; i {
level.dog_clips[i] trigger_on();
level.dog_clips[i] DisconnectPaths();
wait_network_frame();
}

dog_is_alive = true;
while ( dog_is_alive || flag( "dog_round" ) )
{
dog_is_alive = false;
dogs = GetEntArray( "zombie_dog", "targetname" );
for ( i=0; i {
if ( IsAlive(dogs[i]) )
{
dog_is_alive = true;
}
}
wait( 1 );
}

flag_clear( "dog_clips" );
wait(1);
}
}

//
// Allows dogs to be spawned independent of the round spawning
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 {
//update the player array.
players = get_players();
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 );
// level.zombie_total--;
count++;
flag_set( "dog_clips" );
}
}
else
{
if ( IsDefined( level.dog_spawn_func ) )
{
spawn_loc = [[level.dog_spawn_func]]( level.enemy_dog_spawns, favorite_enemy );

ai = spawn_zombie( level.enemy_dog_spawns[0] );
if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_loc thread dog_spawn_fx( ai, spawn_loc );
// level.zombie_total--;
count++;
flag_set( "dog_clips" );
}
}
else
{
// Default method
spawn_point = dog_spawn_factory_logic( level.enemy_dog_spawns, favorite_enemy );
ai = spawn_zombie( spawn_point );

if( IsDefined( ai ) )
{
ai.favoriteenemy = favorite_enemy;
spawn_point thread dog_spawn_fx( ai );
// level.zombie_total--;
count++;
flag_set( "dog_clips" );
}
}
}

waiting_for_next_dog_spawn( count, num_to_spawn );
}

return true;
}

dog_run_think()
{
self endon( "death" );

// these should go back in when the stalking stuff is put back in, the visible check will do for now
//self waittill_any( "dog_running", "dog_combat" );
//self playsound( "zdog_close" );
self waittill( "visible" );

// decrease health
if ( self.health > level.dog_health )
{
self.maxhealth = level.dog_health;
self.health = level.dog_health;
}

// start glowing eyes
assert( IsDefined( self.fx_dog_eye ) );
network_safe_play_fx_on_tag( "dog_fx", 2, level._effect["dog_eye_glow"], self.fx_dog_eye, "tag_origin" );

// start trail
assert( IsDefined( self.fx_dog_trail ) );
network_safe_play_fx_on_tag( "dog_fx", 2, self.fx_dog_trail_type, self.fx_dog_trail, "tag_origin" );
self playloopsound( self.fx_dog_trail_sound );
}

dog_stalk_audio()
{
self endon( "death" );
self endon( "dog_running" );
self endon( "dog_combat" );

while(1)
{
self playsound( "zmb_hellhound_vocals_amb", "stalk_vox_done" );
self waittill( "stalk_vox_done" );
wait randomfloatrange(1,4);
}
}

dog_thundergun_disintegrate( player )
{
self endon( "death" );

self DoDamage( self.health + 666, player.origin, player );
}

dog_thundergun_knockdown( player, gib )
{
self endon( "death" );

damage = int( self.maxhealth * 0.5 );
self DoDamage( damage, player.origin, player );
}

Zombiemode_aiquad
#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include animscripts\zombie_Utility;

init()
{
init_quad_zombie_anims();

level.quad_spawners = GetEntArray( "quad_zombie_spawner", "script_noteworthy" );
array_thread( level.quad_spawners, ::add_spawn_function, maps\_zombiemode_ai_quad::quad_prespawn );
}

wait_for_leap()
{
while ( 1 )
{
wait( 5 );
self.custom_attack = true;
wait( .5 );
self.custom_attack = false;
}
}

#using_animtree( "generic_human" );
quad_prespawn()
{
self.animname = "quad_zombie";

self.custom_idle_setup = maps\_zombiemode_ai_quad::quad_zombie_idle_setup;

self.a.idleAnimOverrideArray = [];
self.a.idleAnimOverrideArray["stand"] = [];
self.a.idleAnimOverrideArray["stand"] = [];
self.a.idleAnimOverrideArray["stand"][0][0] = %ai_zombie_quad_idle;
self.a.idleAnimOverrideWeights["stand"][0][0] = 10;
self.a.idleAnimOverrideArray["stand"][0][1] = %ai_zombie_quad_idle_2;
self.a.idleAnimOverrideWeights["stand"][0][1] = 10;

self.no_eye_glow = true;

self maps\_zombiemode_spawner::zombie_spawn_init( true );

self.maxhealth = int( self.maxhealth * 0.75 );
self.health = self.maxhealth;

self.freezegun_damage = 0;

self.meleeDamage = 45;

self playsound( "zmb_quad_spawn" );

//C. Ayers: This is the TEMP version of the Quad Gas Explosion Mechanic
self.death_explo_radius_zomb = 96; //Radius around the Quad the explosion will affect Zombies
self.death_explo_radius_plr = 96; //Radius around the Quad the explosion will affect Players
self.death_explo_damage_zomb = 1.05; //Damage done to Zombies with explosion, percentage of maxhealth
self.death_gas_radius = 125; //Radius around the Quad the gas will affect Players and Zombies
self.death_gas_time = 7; //Length of time Gas Cloud lasts on a specific quad

if ( isdefined( level.quad_explode ) && level.quad_explode == true )
{
self.deathanimscript = ::quad_post_death;
self.actor_killed_override = ::quad_killed_override;
}

self set_default_attack_properties();

self.thundergun_disintegrate_func = ::quad_thundergun_disintegrate;
self.thundergun_knockdown_func = ::quad_thundergun_knockdown;

//self.custom_damage_func = ::quad_damage_func;

self.pre_teleport_func = ::quad_pre_teleport;
self.post_teleport_func = ::quad_post_teleport;

self.can_explode = false;
self.exploded = false;

self thread quad_trail();

self AllowPitchAngle(1);

//self thread maps\_zombiemode_ai_quad::quad_zombie_think();
if ( isdefined( level.quad_traverse_death_fx ) )
{
self thread [[ level.quad_traverse_death_fx ]]();
}

// jump over quads
self setPhysParams( 15, 0, 24 );
}

quad_zombie_idle_setup()
{

self.a.array["turn_left_45"] = %exposed_tracking_turn45L;
self.a.array["turn_left_90"] = %exposed_tracking_turn90L;
self.a.array["turn_left_135"] = %exposed_tracking_turn135L;
self.a.array["turn_left_180"] = %exposed_tracking_turn180L;
self.a.array["turn_right_45"] = %exposed_tracking_turn45R;
self.a.array["turn_right_90"] = %exposed_tracking_turn90R;
self.a.array["turn_right_135"] = %exposed_tracking_turn135R;
self.a.array["turn_right_180"] = %exposed_tracking_turn180L;
self.a.array["exposed_idle"] = array( %ai_zombie_quad_idle, %ai_zombie_quad_idle_2 );
self.a.array["straight_level"] = %ai_zombie_quad_idle;
self.a.array["stand_2_crouch"] = %ai_zombie_shot_leg_right_2_crawl;
}

init_quad_zombie_anims()
{
// deaths
level.scr_anim["quad_zombie"]["death1"] = %ai_zombie_quad_death;
level.scr_anim["quad_zombie"]["death2"] = %ai_zombie_quad_death_2;
level.scr_anim["quad_zombie"]["death3"] = %ai_zombie_quad_death_3;
level.scr_anim["quad_zombie"]["death4"] = %ai_zombie_quad_death_4;

// run cycles
level.scr_anim["quad_zombie"]["walk1"] = %ai_zombie_quad_crawl;
level.scr_anim["quad_zombie"]["walk2"] = %ai_zombie_quad_crawl;
level.scr_anim["quad_zombie"]["walk3"] = %ai_zombie_quad_crawl;
level.scr_anim["quad_zombie"]["walk4"] = %ai_zombie_quad_crawl_2;
level.scr_anim["quad_zombie"]["walk5"] = %ai_zombie_quad_crawl_2;
level.scr_anim["quad_zombie"]["walk6"] = %ai_zombie_quad_crawl_3;
level.scr_anim["quad_zombie"]["walk7"] = %ai_zombie_quad_crawl_3;
level.scr_anim["quad_zombie"]["walk8"] = %ai_zombie_quad_crawl_3;

level.scr_anim["quad_zombie"]["run1"] = %ai_zombie_quad_crawl_run;
level.scr_anim["quad_zombie"]["run2"] = %ai_zombie_quad_crawl_run_2;
level.scr_anim["quad_zombie"]["run3"] = %ai_zombie_quad_crawl_run_3;
level.scr_anim["quad_zombie"]["run4"] = %ai_zombie_quad_crawl_run_4;
level.scr_anim["quad_zombie"]["run5"] = %ai_zombie_quad_crawl_run_5;
level.scr_anim["quad_zombie"]["run6"] = %ai_zombie_quad_crawl_run;

level.scr_anim["quad_zombie"]["sprint1"] = %ai_zombie_quad_crawl_sprint;
level.scr_anim["quad_zombie"]["sprint2"] = %ai_zombie_quad_crawl_sprint_2;
level.scr_anim["quad_zombie"]["sprint3"] = %ai_zombie_quad_crawl_sprint_3;
level.scr_anim["quad_zombie"]["sprint4"] = %ai_zombie_quad_crawl_sprint;

// run cycles in prone
level.scr_anim["quad_zombie"]["crawl1"] = %ai_zombie_quad_crawl_01;
level.scr_anim["quad_zombie"]["crawl2"] = %ai_zombie_quad_crawl_01;
level.scr_anim["quad_zombie"]["crawl3"] = %ai_zombie_quad_crawl_02;
level.scr_anim["quad_zombie"]["crawl4"] = %ai_zombie_quad_crawl_02;
level.scr_anim["quad_zombie"]["crawl5"] = %ai_zombie_quad_crawl_03;
level.scr_anim["quad_zombie"]["crawl6"] = %ai_zombie_quad_crawl_03;
level.scr_anim["quad_zombie"]["crawl_hand_1"] = %ai_zombie_walk_on_hands_a;
level.scr_anim["quad_zombie"]["crawl_hand_2"] = %ai_zombie_walk_on_hands_b;

level.scr_anim["quad_zombie"]["crawl_sprint1"] = %ai_zombie_crawl_sprint;
level.scr_anim["quad_zombie"]["crawl_sprint2"] = %ai_zombie_crawl_sprint_1;
level.scr_anim["quad_zombie"]["crawl_sprint3"] = %ai_zombie_crawl_sprint_2;

if( !isDefined( level._zombie_melee ) )
{
level._zombie_melee = [];
}
if( !isDefined( level._zombie_walk_melee ) )
{
level._zombie_walk_melee = [];
}
if( !isDefined( level._zombie_run_melee ) )
{
level._zombie_run_melee = [];
}

level._zombie_melee["quad_zombie"] = [];
level._zombie_walk_melee["quad_zombie"] = [];
level._zombie_run_melee["quad_zombie"] = [];

level._zombie_melee["quad_zombie"][0] = %ai_zombie_quad_attack;
level._zombie_melee["quad_zombie"][1] = %ai_zombie_quad_attack_2;
level._zombie_melee["quad_zombie"][2] = %ai_zombie_quad_attack_3;
level._zombie_melee["quad_zombie"][3] = %ai_zombie_quad_attack_4;
level._zombie_melee["quad_zombie"][4] = %ai_zombie_quad_attack_5;
level._zombie_melee["quad_zombie"][5] = %ai_zombie_quad_attack_6;
level._zombie_melee["quad_zombie"][6] = %ai_zombie_quad_attack_double;
level._zombie_melee["quad_zombie"][7] = %ai_zombie_quad_attack_double_2;
level._zombie_melee["quad_zombie"][8] = %ai_zombie_quad_attack_double_3;
level._zombie_melee["quad_zombie"][9] = %ai_zombie_quad_attack_double_4;
level._zombie_melee["quad_zombie"][10] = %ai_zombie_quad_attack_double_5;
level._zombie_melee["quad_zombie"][11] = %ai_zombie_quad_attack_double_6;
/*
level._zombie_run_melee["quad_zombie"][0] = %ai_zombie_quad_attack;
level._zombie_run_melee["quad_zombie"][1] = %ai_zombie_quad_attack;
level._zombie_run_melee["quad_zombie"][2] = %ai_zombie_quad_attack;
level._zombie_walk_melee["quad_zombie"][0] = %ai_zombie_quad_attack;
level._zombie_walk_melee["quad_zombie"][1] = %ai_zombie_quad_attack;
level._zombie_walk_melee["quad_zombie"][2] = %ai_zombie_quad_attack;
level._zombie_walk_melee["quad_zombie"][3] = %ai_zombie_quad_attack;
*/

if( isDefined( level.quad_zombie_anim_override ) )
{
[[ level.quad_zombie_anim_override ]]();
}

// melee in crawl
if( !isDefined( level._zombie_melee_crawl ) )
{
level._zombie_melee_crawl = [];
}
level._zombie_melee_crawl["quad_zombie"] = [];
level._zombie_melee_crawl["quad_zombie"][0] = %ai_zombie_attack_crawl;
level._zombie_melee_crawl["quad_zombie"][1] = %ai_zombie_attack_crawl_lunge;

if( !isDefined( level._zombie_stumpy_melee ) )
{
level._zombie_stumpy_melee = [];
}
level._zombie_stumpy_melee["quad_zombie"] = [];
level._zombie_stumpy_melee["quad_zombie"][0] = %ai_zombie_walk_on_hands_shot_a;
level._zombie_stumpy_melee["quad_zombie"][1] = %ai_zombie_walk_on_hands_shot_b;

// tesla deaths
if( !isDefined( level._zombie_tesla_death ) )
{
level._zombie_tesla_death = [];
}
level._zombie_tesla_death["quad_zombie"] = [];
level._zombie_tesla_death["quad_zombie"][0] = %ai_zombie_quad_death_tesla;
level._zombie_tesla_death["quad_zombie"][1] = %ai_zombie_quad_death_tesla_2;
level._zombie_tesla_death["quad_zombie"][2] = %ai_zombie_quad_death_tesla_3;
level._zombie_tesla_death["quad_zombie"][3] = %ai_zombie_quad_death_tesla_4;

if( !isDefined( level._zombie_tesla_crawl_death ) )
{
level._zombie_tesla_crawl_death = [];
}
level._zombie_tesla_crawl_death["quad_zombie"] = [];
level._zombie_tesla_crawl_death["quad_zombie"][0] = %ai_zombie_tesla_crawl_death_a;
level._zombie_tesla_crawl_death["quad_zombie"][1] = %ai_zombie_tesla_crawl_death_b;

// freezegun deaths
if( !isDefined( level._zombie_freezegun_death ) )
{
level._zombie_freezegun_death = [];
}
level._zombie_freezegun_death["quad_zombie"] = [];
level._zombie_freezegun_death["quad_zombie"][0] = %ai_zombie_quad_freeze_death_a;
level._zombie_freezegun_death["quad_zombie"][1] = %ai_zombie_quad_freeze_death_b;

// deaths
if( !isDefined( level._zombie_deaths ) )
{
level._zombie_deaths = [];
}
level._zombie_deaths["quad_zombie"] = [];
level._zombie_deaths["quad_zombie"][0] = %ai_zombie_quad_death;
level._zombie_deaths["quad_zombie"][1] = %ai_zombie_quad_death_2;
level._zombie_deaths["quad_zombie"][2] = %ai_zombie_quad_death_3;
level._zombie_deaths["quad_zombie"][3] = %ai_zombie_quad_death_4;
level._zombie_deaths["quad_zombie"][4] = %ai_zombie_quad_death_5;
level._zombie_deaths["quad_zombie"][5] = %ai_zombie_quad_death_6;

/*
ground crawl
*/

if( !isDefined( level._zombie_rise_anims ) )
{
level._zombie_rise_anims = [];
}

// set up the arrays
level._zombie_rise_anims["quad_zombie"] = [];

level._zombie_rise_anims["quad_zombie"][1]["walk"][0] = %ai_zombie_quad_traverse_ground_crawlfast;

level._zombie_rise_anims["quad_zombie"][1]["run"][0] = %ai_zombie_quad_traverse_ground_crawlfast;

level._zombie_rise_anims["quad_zombie"][1]["sprint"][0] = %ai_zombie_quad_traverse_ground_crawlfast;

level._zombie_rise_anims["quad_zombie"][2]["walk"][0] = %ai_zombie_quad_traverse_ground_crawlfast;

// ground crawl death
if( !isDefined( level._zombie_rise_death_anims ) )
{
level._zombie_rise_death_anims = [];
}

level._zombie_rise_death_anims["quad_zombie"] = [];

level._zombie_rise_death_anims["quad_zombie"][1]["in"][0] = %ai_zombie_traverse_ground_v1_deathinside;
level._zombie_rise_death_anims["quad_zombie"][1]["in"][1] = %ai_zombie_traverse_ground_v1_deathinside_alt;

level._zombie_rise_death_anims["quad_zombie"][1]["out"][0] = %ai_zombie_traverse_ground_v1_deathoutside;
level._zombie_rise_death_anims["quad_zombie"][1]["out"][1] = %ai_zombie_traverse_ground_v1_deathoutside_alt;

level._zombie_rise_death_anims["quad_zombie"][2]["in"][0] = %ai_zombie_traverse_ground_v2_death_low;
level._zombie_rise_death_anims["quad_zombie"][2]["in"][1] = %ai_zombie_traverse_ground_v2_death_low_alt;

level._zombie_rise_death_anims["quad_zombie"][2]["out"][0] = %ai_zombie_traverse_ground_v2_death_high;
level._zombie_rise_death_anims["quad_zombie"][2]["out"][1] = %ai_zombie_traverse_ground_v2_death_high_alt;

//taunts
if( !isDefined( level._zombie_run_taunt ) )
{
level._zombie_run_taunt = [];
}
if( !isDefined( level._zombie_board_taunt ) )
{
level._zombie_board_taunt = [];
}
level._zombie_run_taunt["quad_zombie"] = [];
level._zombie_board_taunt["quad_zombie"] = [];

level._zombie_board_taunt["quad_zombie"][0] = %ai_zombie_quad_taunt;
level._zombie_board_taunt["quad_zombie"][1] = %ai_zombie_quad_taunt_2;
level._zombie_board_taunt["quad_zombie"][2] = %ai_zombie_quad_taunt_3;
level._zombie_board_taunt["quad_zombie"][3] = %ai_zombie_quad_taunt_4;
level._zombie_board_taunt["quad_zombie"][4] = %ai_zombie_quad_taunt_5;
level._zombie_board_taunt["quad_zombie"][5] = %ai_zombie_quad_taunt_6;

level._effect[ "quad_explo_gas" ] = LoadFX( "maps/zombie/fx_zombie_quad_gas_nova6" );
level._effect[ "quad_trail" ] = Loadfx( "maps/zombie/fx_zombie_quad_trail" );
}

quad_vox()
{
self endon( "death" );

wait( 5 );

quad_wait = 5;

while(1)
{
players = getplayers();

for(i=0;i {
if(DistanceSquared(self.origin, players[i].origin) > 1200 * 1200)
{
self playsound( "zmb_quad_amb" );
quad_wait = 7;
}
else if(DistanceSquared(self.origin, players[i].origin) > 200 * 200)
{
self playsound( "zmb_quad_vox" );
quad_wait = 5;
}
else if(DistanceSquared(self.origin, players[i].origin) {
wait(.05);
}
}
wait randomfloatrange( 1, quad_wait );
}
}

quad_close()
{
self endon( "death" );

while(1)
{
players = getplayers();

for(i=0;i {
if ( is_player_valid( players[i], true ) )
{
if(DistanceSquared(self.origin, players[i].origin) {
self playsound( "zmb_quad_close" );
wait randomfloatrange( 1, 2 );
}
}
}

wait_network_frame();
}
}

set_leap_attack_properties()
{
self.pathEnemyFightDist = 320;
// self.meleeAttackDist = 350;
self.goalradius = 320;

self.maxsightdistsqrd = 256 * 256;
self.can_leap = true;
}

set_default_attack_properties()
{
self.pathEnemyFightDist = 64;
self.meleeAttackDist = 64;
self.goalradius = 16;

self.maxsightdistsqrd = 128 * 128;
self.can_leap = false;
}

check_wait()
{
min_dist = 96;
max_dist = 144;
height_tolerance = 32;

if ( isdefined( self.enemy ) )
{
delta = self.enemy.origin - self.origin;
dist = length( delta );

z_check = true;
z_diff = abs( self.enemy.origin[2] - self.origin[2] );
if ( z_diff > height_tolerance )
{
z_check = false;
}

if ( dist > min_dist && dist {
cansee = SightTracePassed( self.origin, self.enemy.origin, false, undefined );
if( cansee )
self set_leap_attack_properties();
else
self set_default_attack_properties();
}
else
{
self set_default_attack_properties();
}
}
}

quad_zombie_think()
{
self endon( "death" );

// /#
// self animscripts\debug::debugPushState( "quad_zombie_think" );
// #/

self.specialAttack = maps\_zombiemode_ai_quad::TryLeap;
self.state = "waiting";
self.isAttacking = false;
self.nextSpecial = GetTime();

for (;;)
{
switch ( self.state )
{
case "waiting":
check_wait();
break;

case "leaping":
break;
}

wait_network_frame();
}

// /#
// self animscripts\debug::debugPopState();
// #/
}

trackCollision()
{
self endon( "death" );
self endon( "stop_coll" );

while ( 1 )
{
check = self GetHitEntType();
if ( check != "none" )
{
/#
self animscripts\debug::debugPushState( check );
#/

self thread quad_stop_leap();
self notify( "stop_leap" );
self notify( "stop_coll" );
}
wait_network_frame();
}
}

quad_finish_leap()
{
self endon( "death" );

/#
self animscripts\debug::debugPushState( "quad_finish_leap" );
#/

self.state = "waiting";
self.isAttacking = false;
self.nextSpecial = GetTime() + 3000;

self animMode("none");
self.syncedMeleeTarget = undefined;
self OrientMode("face enemy");

self thread animscripts\zombie_combat::main();

/#
self animscripts\debug::debugPopState();
#/
}

quad_stop_leap()
{
self endon( "death" );

self SetFlaggedAnimKnobAllRestart("attack",%ai_zombie_quad_attack_leap_loop_out, %body, 1, .1, 1);
self animscripts\zombie_shared::DoNoteTracks( "attack" );

self quad_finish_leap();
}

quad_leap_attack()
{
self endon( "death" );
self endon( "stop_leap" );

/#
self animscripts\debug::debugPushState( "quad_leap_attack" );
#/

self.state = "leaping";
self.isAttacking = true;

// self ClearAnim(%stand_and_crouch, 0.1);
if( IsDefined( self.enemy ) )
{
self.syncedMeleeTarget = self.enemy;
angles = VectorToAngles( self.enemy.origin - self.origin );
self OrientMode( "face angle", angles[1] );
}

// restore attack properties to prevent code trying to control animmode
self set_default_attack_properties();
self.goalradius = 4;

self animMode("nogravity");

leap_in = %ai_zombie_quad_attack_leap_loop_in;
delta = GetMoveDelta( leap_in, 0, 1 );

self SetFlaggedAnimKnobAllRestart("attack",%ai_zombie_quad_attack_leap_loop_in, %body, 1, .1, 1);
animscripts\traverse\zombie_shared::wait_anim_length(leap_in, .02);
// self animscripts\zombie_shared::DoNoteTracks( "attack" );

use_loop = false;
if ( use_loop )
{
leap_loop = %ai_zombie_quad_attack_leap_loop;

self thread trackCollision();
self SetFlaggedAnimKnobAllRestart("attack",leap_loop, %body, 1, .1, 1);

delta = GetMoveDelta( leap_loop, 0, 1 );
anim_dist = length( delta );
anim_time = getanimlength( leap_loop );
rate = anim_dist / getanimlength( leap_loop );

goal_dist = length( self.enemy.origin - self.origin );
goal_dist -= 16; // give some room for player radius

//time = goal_dist / rate;
//if ( time > 0 )
//{
// self animscripts\zombie_shared::DoNoteTracksForTime( time, "attack" );
//}
animscripts\traverse\zombie_shared::wait_anim_length(leap_loop, .02);
// self animscripts\zombie_shared::DoNoteTracksForTime( anim_time, "attack" );
}

self notify( "stop_coll" );

leap_out = %ai_zombie_quad_attack_leap_attack;

if ( isdefined(self.enemy) )
{
delta = self.enemy.origin - self.origin;
deltaF = ( delta[0], delta[1], 0 );
attack_dist = length( deltaF );
/#
self animscripts\debug::debugPushState( "attack dist = " + attack_dist );
#/
if ( attack_dist {
leap_out = %ai_zombie_quad_attack_leap_attack;
}
}

delta = GetMoveDelta( leap_out, 0, 1 );

self SetFlaggedAnimKnobAllRestart("attack",leap_out, %body, 1, .1, 1);

while ( 1 )
{
self waittill("attack", note);
if ( note == "end" )
{
break;
}
else if ( note == "fire" )
{
if ( !IsDefined( self.enemy ) )
{
break;
}

oldhealth = self.enemy.health;
self melee();
}
else if ( note == "gravity on" )
{
self animMode("none");
}
}

/#
self animscripts\debug::debugPopState();
#/

quad_finish_leap();

/#
self animscripts\debug::debugPopState();
#/
}

TryLeap()
{
// prevent other combat until leap is done
if ( self.state == "leaping" )
{
return true;
}

if ( !IsDefined( self.enemy ) )
{
return false;
}

// early out
if ( DistanceSquared( self.origin, self.enemy.origin ) > 512*512 )
{
animscripts\zombie_melee::debug_melee( "Not doing melee - Distance to enemy is more than 512 units." );
return false;
}

if ( self.a.pose == "prone" )
{
return false;
}

if ( !self.can_leap )
{
return false;
}

self thread maps\_zombiemode_ai_quad::quad_leap_attack();
self notify( "special_attack" );

return true;
}

quad_thundergun_disintegrate( player )
{
self endon( "death" );

self DoDamage( self.health + 666, player.origin, player );
}

quad_thundergun_knockdown( player, gib )
{
self endon( "death" );

damage = int( self.maxhealth * 0.5 );
self DoDamage( damage, player.origin, player );
}

quad_gas_explo_death()
{
death_vars = [];
death_vars["explo_radius_zomb"] = self.death_explo_radius_zomb;
death_vars["explo_radius_plr"] = self.death_explo_radius_plr;
death_vars["explo_damage_zomb"] = self.death_explo_damage_zomb;
death_vars["gas_radius"] = self.death_gas_radius;
death_vars["gas_time"] = self.death_gas_time;

self thread quad_death_explo( self.origin, death_vars );
level thread quad_gas_area_of_effect( self.origin, death_vars );
self Delete();
}

quad_death_explo( origin, death_vars )
{
playsoundatposition( "zmb_quad_explo", origin );
PlayFx( level._effect["dog_gib"], origin );

players = get_players();
zombies = GetAIArray( "axis" );

/*
for(i = 0; i {
if( Distance( origin, zombies[i].origin ) {
if( zombies[i].animname != "quad_zombie" )
{
zombies[i] DoDamage( zombies[i].maxhealth * death_vars["explo_damage_zomb"], origin );

if( zombies[i].health {
zombies[i] StartRagdoll();
zombies[i] LaunchRagdoll( zombies[i].origin - origin );
}
}
}
}
*/

for(i = 0; i {
if( Distance( origin, players[i].origin ) {
players[i] ShellShock( "explosion", 2.5 );
}
}

self.exploded = true;
self RadiusDamage( origin, death_vars["explo_radius_zomb"], level.zombie_health, level.zombie_health, self, "MOD_EXPLOSIVE" );


//PhysicsExplosionSphere( origin, death_vars["explo_radius_zomb"], 175, 2 );
}

quad_damage_func( player )
{
if ( self.exploded )
{
//player ShellShock( "explosion", 2.5 );
return 0;
}

return self.meleeDamage;
}

quad_gas_area_of_effect( origin, death_vars )
{
effectArea = spawn( "trigger_radius", origin, 0, death_vars["gas_radius"], 100 );
//soundent = Spawn( "script_origin", origin );

//soundent PlayLoopSound( "wpn_gas_hiss_lp", 1 );
PlayFX( level._effect[ "quad_explo_gas" ], origin );

gas_time = 0;

while( gas_time {
players = get_players();
// zombies = GetAIArray( "axis" );

for(i = 0; i {
if( players[i] IsTouching( effectArea ))
{
//players[i] ShellShock( "flashbang", 1.5 );
players[i] setblur( 4, .1 );
}
else
{
players[i] setblur( 0, .5 );
}
}

wait(1);
gas_time = gas_time + 1;
}

players = get_players();
for ( i = 0; i {
players[i] setblur( 0, .5 );
}

//soundent StopLoopSound( 1 );
effectArea Delete();
//wait(1);
//soundent Delete();
}

quad_trail()
{
self endon( "death" );
self waittill( "quad_end_traverse_anim" );

//Add in the smoke effect from the dogs
self.fx_quad_trail = Spawn( "script_model", self GetTagOrigin( "tag_origin" ) );
self.fx_quad_trail.angles = self GetTagAngles( "tag_origin" );
self.fx_quad_trail SetModel( "tag_origin" );
self.fx_quad_trail LinkTo( self, "tag_origin" );
maps\_zombiemode_net::network_safe_play_fx_on_tag( "quad_fx", 2, level._effect[ "quad_trail" ], self.fx_quad_trail, "tag_origin" );
}

quad_post_death()
{
if ( isdefined( self.fx_quad_trail ) )
{
self.fx_quad_trail unlink();
self.fx_quad_trail delete();
}

if ( self.can_explode )
{
self thread quad_gas_explo_death();
}
}

quad_killed_override( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime )
{
if ( sMeansOfDeath == "MOD_PISTOL_BULLET" || sMeansOfDeath == "MOD_RIFLE_BULLET" )
{
self.can_explode = true;
}
else
{
self.can_explode = false;

if ( isdefined( self.fx_quad_trail ) )
{
self.fx_quad_trail unlink();
self.fx_quad_trail delete();
}
}
}

quad_pre_teleport()
{
if ( isDefined( self.fx_quad_trail ) )
{
self.fx_quad_trail unlink();
self.fx_quad_trail delete();
wait( .1 );
}
}

quad_post_teleport()
{
if ( isDefined( self.fx_quad_trail ) )
{
self.fx_quad_trail unlink();
self.fx_quad_trail delete();
}

if ( self.health > 0 )
{
self.fx_quad_trail = Spawn( "script_model", self GetTagOrigin( "tag_origin" ) );
self.fx_quad_trail.angles = self GetTagAngles( "tag_origin" );
self.fx_quad_trail SetModel( "tag_origin" );
self.fx_quad_trail LinkTo( self, "tag_origin" );
maps\_zombiemode_net::network_safe_play_fx_on_tag( "quad_fx", 2, level._effect[ "quad_trail" ], self.fx_quad_trail, "tag_origin" );
}
}

Link to comment

Zombiemode_aiaudio

#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include maps\_music;
#include maps\_busing;

audio_init()
{
level init_audio_aliases();
level init_music_states();
level thread init_audio_functions();
}

//All Vox should be found in this section.
//If there is an Alias that needs to be changed, check here first.
init_audio_aliases()
{
//**Announcer Vox Categories**\\
//ARRAY and PREFIX: Setting up a prefix and array for all Devil lines
level.devil_vox = [];
level.devil_vox["prefix"] = "zmb_vox_ann_";

//POWERUPS: Play after a player picks up a powerup; plays for ALL players
level.devil_vox["powerup"] = [];
level.devil_vox["powerup"]["carpenter"] = "carpenter";
level.devil_vox["powerup"]["insta_kill"] = "instakill";
level.devil_vox["powerup"]["double_points"] = "doublepoints";
level.devil_vox["powerup"]["nuke"] = "nuke";
level.devil_vox["powerup"]["full_ammo"] = "maxammo";
level.devil_vox["powerup"]["fire_sale"] = "firesale";
level.devil_vox["powerup"]["fire_sale_short"] = "firesale_short";
level.devil_vox["powerup"]["minigun"] = "death_machine";
level.devil_vox["powerup"]["bonfire_sale"] = "bonfiresale";
level.devil_vox["powerup"]["all_revive"] = undefined;

//**Player Zombie Vox Categories**\\
//ARRAY and PREFIX: Creating the main player vox array, setting up the default alias prefix that will be added onto all lines
level.plr_vox = [];
level.plr_vox["prefix"] = "vox_plr_";

//GENERAL: Any lines that do not fit into an overall larger category.
level.plr_vox["general"] = [];
level.plr_vox["general"]["crawl_spawn"] = "spawn_crawl"; //OCCURS WHEN THE PLAYER SHOOTS THE LEGS OFF A ZOMBIE, CREATING A CRAWLER
level.plr_vox["general"]["crawl_spawn_response"] = "resp_spawn_crawl"; //RESPONSE TO ABOVE
level.plr_vox["general"]["dog_spawn"] = "spawn_dog"; //OCCURS AT THE BEGINNING OF A DOG ROUND
level.plr_vox["general"]["dog_spawn_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["quad_spawn"] = "spawn_quad"; //OCCURS WHEN QUADS FIRST SPAWN THROUGH THE ROOF
level.plr_vox["general"]["quad_spawn_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["ammo_low"] = "ammo_low"; //OCCURS WHEN THE PLAYERS AMMO IN A WEAPON IS BELOW 5
level.plr_vox["general"]["ammo_low_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["ammo_out"] = "ammo_out"; //OCCURS WHEN THE PLAYER HAS NO MORE AMMO FOR A WEAPON
level.plr_vox["general"]["ammo_out_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["door_deny"] = "nomoney"; //CURRENTLY UNUSED: INTENDED FOR LOCKED, POWER-DRIVEN DOORS
level.plr_vox["general"]["door_deny_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["perk_deny"] = "nomoney"; //OCCURS WHEN THE PLAYER CANNOT AFFORD A PERK OR ALREADY HAS THE PERK
level.plr_vox["general"]["perk_deny_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["intro"] = "level_start"; //CURRENTLY UNUSED: INTENDED AS THE FIRST LINE WHEN THE GAME BEGINS
level.plr_vox["general"]["intro_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["shoot_arm"] = "shoot_limb"; //OCCURS WHEN THE PLAYER SHOOTS OFF AN ARM
level.plr_vox["general"]["shoot_arm_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["box_move"] = "box_move"; //OCCURS WHEN THE PLAYER CAUSES THE MAGIC BOX TO CHANGE POSITION
level.plr_vox["general"]["box_move_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["no_money"] = "nomoney"; //OCCURS WHEN THE PLAYER HAS NO MONEY AND TRIES TO BUY A WEAPON
level.plr_vox["general"]["no_money_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["oh_shit"] = "ohshit"; //OCCURS WHEN 4 OR MORE ZOMBIES ARE WITHIN 250 UNITS OF THE PLAYER
level.plr_vox["general"]["oh_shit_response"] = "resp_ohshit"; //RESPONSE TO ABOVE
level.plr_vox["general"]["revive_down"] = "revive_down"; //OCCURS WHEN THE PLAYER GOES INTO LAST STAND
level.plr_vox["general"]["revive_down_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["revive_up"] = "revive_up"; //OCCURS WHEN THE PLAYER REVIVES A TEAMMATE
level.plr_vox["general"]["revive_up_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["general"]["crawl_hit"] = "crawler_hit"; //OCCURS WHEN THE PLAYER IS HIT BY A CRAWLER
level.plr_vox["general"]["crawl_hit_response"] = undefined; //RESPONSE TO ABOVE

//PERKS: Play whenever a player buys a perk.
level.plr_vox["perk"] = [];
level.plr_vox["perk"]["specialty_armorvest"] = "perk_jugga"; //JUGGERNOG PURCHASE
level.plr_vox["perk"]["specialty_armorvest_response"] = undefined; //JUGGERNOG PURCHASE RESPONSE
level.plr_vox["perk"]["specialty_quickrevive"] = "perk_revive"; //REVIVE SODA PURCHASE
level.plr_vox["perk"]["specialty_quickrevive_response"] = undefined; //REVIVE SODA PURCHASE RESPONSE
level.plr_vox["perk"]["specialty_fastreload"] = "perk_speed"; //SPEED COLA PURCHASE
level.plr_vox["perk"]["specialty_fastreload_response"] = undefined; //SPEED COLA PURCHASE RESPONSE
level.plr_vox["perk"]["specialty_rof"] = "perk_doubletap"; //DOUBLETAP ROOTBEER PURCHASE
level.plr_vox["perk"]["specialty_rof_response"] = undefined; //DOUBLETAP ROOTBEER PURCHASE RESPONSE

//POWERUPS: Play whenever a player picks up a powerup
level.plr_vox["powerup"] = [];
level.plr_vox["powerup"]["nuke"] = "powerup_nuke"; //NUKE PICKUP
level.plr_vox["powerup"]["nuke_response"] = undefined; //NUKE PICKUP RESPONSE
level.plr_vox["powerup"]["insta_kill"] = "powerup_insta"; //INSTA-KILL PICKUP
level.plr_vox["powerup"]["insta_kill_response"] = undefined; //INSTA-KILL PICKUP RESPONSE
level.plr_vox["powerup"]["full_ammo"] = "powerup_ammo"; //MAX AMMO PICKUP
level.plr_vox["powerup"]["full_ammo_response"] = undefined; //MAX AMMO PICKUP RESPONSE
level.plr_vox["powerup"]["double_points"] = "powerup_double"; //DOUBLE POINTS PICKUP
level.plr_vox["powerup"]["double_points_response"] = undefined; //DOUBLE POINTS PICKUP RESPONSE
level.plr_vox["powerup"]["carpenter"] = "powerup_carp"; //CARPENTER PICKUP
level.plr_vox["powerup"]["carpenter_response"] = undefined; //CARPENTER RESPONSE
level.plr_vox["powerup"]["firesale"] = "powerup_firesale"; //FIRESALE PICKUP
level.plr_vox["powerup"]["firesale_response"] = undefined; //FIRESALE RESPONSE

//WEAPON KILLS: Plays whenever certain Kill Criteria are met
level.plr_vox["kill"] = [];
level.plr_vox["kill"]["melee"] = "kill_melee"; //PLAYER KILLS A ZOMBIE USING MELEE
level.plr_vox["kill"]["melee_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["melee_instakill"] = "kill_insta"; //PLAYER KILLS A ZOMBIE USING MELEE WHILE INSTAKILL IS ACTIVE
level.plr_vox["kill"]["melee_instakill_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["weapon_instakill"] = "kill_insta"; //PLAYER KILLS A ZOMBIE USING ANY WEAPON WHILE INSTAKILL IS ACTIVE
level.plr_vox["kill"]["weapon_instakill_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["closekill"] = "kill_close"; //PLAYER KILLS A ZOMBIE WHO IS WITHIN 64 UNITS OF THE PLAYER
level.plr_vox["kill"]["closekill_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["damage"] = "kill_damaged"; //WHEN THE PLAYER KILLS A ZOMBIE AFTER RECEIVING DAMAGE FROM SAID ZOMBIE
level.plr_vox["kill"]["damage_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["streak"] = "kill_streak"; //OCCURS WHEN THE PLAYER KILLS OVER 6 ZOMBIES WITHIN A SMALL TIME PERIOD
level.plr_vox["kill"]["streak_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["headshot"] = "kill_headshot"; //PLAYER KILLS A ZOMBIE WITH A HEADSHOT OVER 400 UNITS AWAY
level.plr_vox["kill"]["headshot_response"] = "resp_kill_headshot"; //RESPONSE TO ABOVE
level.plr_vox["kill"]["explosive"] = "kill_explo"; //PLAYER KILLS A ZOMBIE USING EXPLOSIVES
level.plr_vox["kill"]["explosive_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["flame"] = "kill_flame"; //PLAYER KILLS A ZOMBIE USING FLAME
level.plr_vox["kill"]["flame_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["raygun"] = "kill_ray"; //PLAYER KILLS A ZOMBIE USING THE RAYGUN
level.plr_vox["kill"]["raygun_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["bullet"] = "kill_streak"; //PLAYER KILLS A ZOMBIE USING ANY BULLET BASED WEAPON
level.plr_vox["kill"]["bullet_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["tesla"] = "kill_tesla"; //PLAYER KILLS 4 OR MORE ZOMBIES WITH ONE SHOT OF THE TESLA GUN
level.plr_vox["kill"]["tesla_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["monkey"] = "kill_monkey"; //WHEN THE PLAYER KILLS A ZOMBIE USING THE MONKEYBOMB
level.plr_vox["kill"]["monkey_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["thundergun"] = "kill_thunder"; //PLAYER KILLS A ZOMBIE USING THE THUNDERGUN
level.plr_vox["kill"]["thundergun_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["freeze"] = "kill_freeze"; //PLAYER KILLS A ZOMBIE USING THE FREEZEGUN
level.plr_vox["kill"]["freeze_response"] = undefined;
level.plr_vox["kill"]["crawler"] = "kill_crawler"; //PLAYER KILLS A CRAWLING ZOMBIE
level.plr_vox["kill"]["crawler_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["hellhound"] = "kill_hellhound"; //PLAYER KILLS A HELLHOUND
level.plr_vox["kill"]["hellhound_response"] = undefined; //RESPONSE TO ABOVE
level.plr_vox["kill"]["quad"] = "kill_quad"; //PLAYER KILLS A QUAD ZOMBIE
level.plr_vox["kill"]["quad_response"] = undefined; //RESPONSE TO ABOVE

//WEAPON PICKUPS: Each will play after the Player buys or gets a weapon from the box. Broken into weapon categories.
//Can be made weapon specific, if the need arises.
level.plr_vox["weapon_pickup"] = [];
level.plr_vox["weapon_pickup"]["pistol"] = "wpck_crappy";
level.plr_vox["weapon_pickup"]["pistol_response"] = undefined;
level.plr_vox["weapon_pickup"]["smg"] = "wpck_smg";
level.plr_vox["weapon_pickup"]["smg_response"] = undefined;
level.plr_vox["weapon_pickup"]["dualwield"] = "wpck_dual";
level.plr_vox["weapon_pickup"]["dualwield_response"] = undefined;
level.plr_vox["weapon_pickup"]["shotgun"] = "wpck_shotgun";
level.plr_vox["weapon_pickup"]["shotgun_response"] = undefined;
level.plr_vox["weapon_pickup"]["rifle"] = "wpck_sniper";
level.plr_vox["weapon_pickup"]["rifle_response"] = undefined;
level.plr_vox["weapon_pickup"]["burstrifle"] = "wpck_mg";
level.plr_vox["weapon_pickup"]["burstrifle_response"] = undefined;
level.plr_vox["weapon_pickup"]["assault"] = "wpck_mg";
level.plr_vox["weapon_pickup"]["assault_response"] = undefined;
level.plr_vox["weapon_pickup"]["sniper"] = "wpck_sniper";
level.plr_vox["weapon_pickup"]["sniper_response"] = undefined;
level.plr_vox["weapon_pickup"]["mg"] = "wpck_mg";
level.plr_vox["weapon_pickup"]["mg_response"] = undefined;
level.plr_vox["weapon_pickup"]["launcher"] = "wpck_launcher";
level.plr_vox["weapon_pickup"]["launcher_response"] = undefined;
level.plr_vox["weapon_pickup"]["grenade"] = "wpck_crappy";
level.plr_vox["weapon_pickup"]["grenade_response"] = undefined;
level.plr_vox["weapon_pickup"]["bowie"] = "wpck_bowie";
level.plr_vox["weapon_pickup"]["bowie_response"] = undefined;
level.plr_vox["weapon_pickup"]["raygun"] = "wpck_raygun";
level.plr_vox["weapon_pickup"]["raygun_response"] = undefined;
level.plr_vox["weapon_pickup"]["monkey"] = "wpck_monkey";
level.plr_vox["weapon_pickup"]["monkey_response"] = "resp_wpck_monkey";
level.plr_vox["weapon_pickup"]["tesla"] = "wpck_tesla";
level.plr_vox["weapon_pickup"]["tesla_response"] = undefined;
level.plr_vox["weapon_pickup"]["thunder"] = "wpck_thunder";
level.plr_vox["weapon_pickup"]["thunder_response"] = undefined;
level.plr_vox["weapon_pickup"]["freezegun"] = "wpck_freeze";
level.plr_vox["weapon_pickup"]["freezegun_response"] = undefined;
level.plr_vox["weapon_pickup"]["crossbow"] = "wpck_launcher";
level.plr_vox["weapon_pickup"]["crossbow_response"] = undefined;
level.plr_vox["weapon_pickup"]["upgrade"] = "wpck_upgrade";
level.plr_vox["weapon_pickup"]["upgrade_response"] = undefined;
level.plr_vox["weapon_pickup"]["upgrade_wait"] = "wpck_upgrade_wait";
level.plr_vox["weapon_pickup"]["upgrade_wait_response"] = undefined;
level.plr_vox["weapon_pickup"]["favorite"] = "wpck_favorite";
level.plr_vox["weapon_pickup"]["favorite_response"] = undefined;
level.plr_vox["weapon_pickup"]["favorite_upgrade"] = "wpck_favorite_upgrade";
level.plr_vox["weapon_pickup"]["favorite_upgrade_response"] = undefined;

//EGGS and OTHER STUFF: Egg lines, achievements, etc
level.plr_vox["eggs"] = [];
level.plr_vox["eggs"]["achievement"] = "achievement";
level.plr_vox["eggs"]["music_activate"] = "secret";
level.plr_vox["eggs"]["meteors"] = "egg_pedastool";
level.plr_vox["eggs"]["room_screen"] = "egg_room_screen";
level.plr_vox["eggs"]["room_dress"] = "egg_room_dress";
level.plr_vox["eggs"]["room_lounge"] = "egg_room_lounge";
level.plr_vox["eggs"]["room_rest"] = "egg_room_rest";
level.plr_vox["eggs"]["room_alley"] = "egg_room_alley";
level.plr_vox["eggs"]["portrait_dempsey"] = "egg_port_dempsey";
level.plr_vox["eggs"]["portrait_nikolai"] = "egg_port_nikolai";
level.plr_vox["eggs"]["portrait_takeo"] = "egg_port_takeo";
level.plr_vox["eggs"]["portrait_richtofan"] = "egg_port_richtofan";
level.plr_vox["eggs"]["portrait_empty"] = "egg_port_empty";

//**ZOMBIE VOCALIZATIONS**\\
//ARRAY and PREFIX: Setting up a prefix and array for all Zombie vocalizations
level.zmb_vox = [];
level.zmb_vox["prefix"] = "zmb_vocals_";

//Standard Zombies
level.zmb_vox["zombie"] = [];
level.zmb_vox["zombie"]["ambient"] = "zombie_ambience";
level.zmb_vox["zombie"]["sprint"] = "zombie_sprint";
level.zmb_vox["zombie"]["attack"] = "zombie_attack";
level.zmb_vox["zombie"]["teardown"] = "zombie_teardown";
level.zmb_vox["zombie"]["taunt"] = "zombie_taunt";
level.zmb_vox["zombie"]["behind"] = "zombie_behind";
level.zmb_vox["zombie"]["death"] = "zombie_death";
level.zmb_vox["zombie"]["crawler"] = "zombie_crawler";

//Quad Zombies
level.zmb_vox["quad_zombie"] = [];
level.zmb_vox["quad_zombie"]["ambient"] = "quad_ambience";
level.zmb_vox["quad_zombie"]["sprint"] = "quad_sprint";
level.zmb_vox["quad_zombie"]["attack"] = "quad_attack";
level.zmb_vox["quad_zombie"]["behind"] = "quad_behind";
level.zmb_vox["quad_zombie"]["death"] = "quad_death";

//Thief Zombies
level.zmb_vox["thief_zombie"] = [];
level.zmb_vox["thief_zombie"]["ambient"] = "thief_ambience";
level.zmb_vox["thief_zombie"]["sprint"] = "thief_sprint";
level.zmb_vox["thief_zombie"]["steal"] = "thief_steal";
level.zmb_vox["thief_zombie"]["death"] = "thief_death";
level.zmb_vox["thief_zombie"]["anger"] = "thief_anger";

//Boss Zombies
level.zmb_vox["boss_zombie"] = [];
level.zmb_vox["boss_zombie"]["ambient"] = "boss_ambience";
level.zmb_vox["boss_zombie"]["sprint"] = "boss_sprint";
level.zmb_vox["boss_zombie"]["attack"] = "boss_attack";
level.zmb_vox["boss_zombie"]["behind"] = "boss_behind";
level.zmb_vox["boss_zombie"]["death"] = "boss_death";

}

init_audio_functions()
{
flag_wait( "all_players_connected" );

players = get_players();
for( i = 0; i {
players[i] thread zombie_behind_vox();
players[i] thread player_killstreak_timer();
players[i] thread oh_shit_vox();
}
}

//Plays a specific Zombie vocal when they are close behind the player
//Self is the Player(s)
zombie_behind_vox()
{
self endon("disconnect");
self endon("death");

while(1)
{
wait(1);

zombs = GetAISpeciesArray("axis");

for(i=0;i {
if(!isDefined(zombs[i]))
{
continue;
}

if(zombs[i].isdog)
{
continue;
}

dist = 200;
z_dist = 50;
alias = level.vox_behind_zombie;

if(IsDefined(zombs[i].zombie_move_speed))
{
switch(zombs[i].zombie_move_speed)
{
case "walk": dist = 200;break;
case "run": dist = 250;break;
case "sprint": dist = 275;break;
}
}
if(DistanceSquared(zombs[i].origin,self.origin) {
yaw = self animscripts\utility::GetYawToSpot(zombs[i].origin );
z_diff = self.origin[2] - zombs[i].origin[2];
if( (yaw 95) && abs( z_diff ) {
zombs[i] thread maps\_zombiemode_audio::do_zombies_playvocals( "behind", zombs[i].animname );
}
}
}
}
}

do_zombies_playvocals( alias_type, zombie_type )
{
self endon( "death" );

if( !IsDefined( zombie_type ) )
{
zombie_type = "zombie";
}

if( !IsDefined( self.talking ) )
{
self.talking = false;
}

//DEBUG SECTION
if( !IsDefined( level.zmb_vox[zombie_type] ) )
{
/#
IPrintLnBold( "AUDIO - ZOMBIE TYPE: " + zombie_type + " has NO aliases set up for it." );
#/
return;
}

if( !IsDefined( level.zmb_vox[zombie_type][alias_type] ) )
{
/#
IPrintLnBold( "AUDIO - ZOMBIE TYPE: " + zombie_type + " has NO aliases set up for ALIAS_TYPE: " + alias_type );
#/
return;
}

alias = level.zmb_vox["prefix"] + level.zmb_vox[zombie_type][alias_type];

if( alias_type == "attack" || alias_type == "behind" || alias_type == "death" || alias_type == "anger" || alias_type == "steal" )
{
self PlaySound( alias );
}
else if( !self.talking )
{
self.talking = true;
self PlaySound( alias, "sounddone" );
self waittill( "sounddone" );
self.talking = false;
}
}

oh_shit_vox()
{
self endon("disconnect");
self endon("death");

while(1)
{
wait(1);

players = getplayers();
zombs = GetAISpeciesArray("axis");

if( players.size > 1 )
{
close_zombs = 0;
for( i=0; i {
if( DistanceSquared( zombs[i].origin, self.origin ) {
close_zombs ++;
}
}
if( close_zombs > 4 )
{
if( randomintrange( 0, 20 ) {
self create_and_play_dialog( "general", "oh_shit" );
}
}
}
}
}

//**Player Dialog - The following functions all serve to play Player dialog
//**To use create_and_play_dialog, _zombiemode_audio must be included in the GSC you're using the function in, or you must
//**call the function like so: player maps\_zombiemode_audio::create_and_play_dialog()

create_and_play_dialog( category, type, response, force_variant )
{
waittime = .25;

/#
if( GetDvarInt( #"debug_audio" ) > 0 )
level thread dialog_debugger( category, type );
#/

if( !IsDefined( level.plr_vox[category][type] ) )
{
//IPrintLnBold( "No Category: " + category + " and Type: " + type );
return;
}

alias_suffix = level.plr_vox[category][type];

if( IsDefined( response ) )
alias_suffix = response + alias_suffix;

index = maps\_zombiemode_weapons::get_player_index(self);
prefix = level.plr_vox["prefix"] + index + "_";

if( !IsDefined ( self.sound_dialog ) )
{
self.sound_dialog = [];
self.sound_dialog_available = [];
}

if ( !IsDefined ( self.sound_dialog[ alias_suffix ] ) )
{
num_variants = maps\_zombiemode_spawner::get_number_variants( prefix + alias_suffix );

//TOOK OUT THE ASSERT AND ADDED THIS CHECK FOR LOCS
if( num_variants {
return;
}
//assertex( num_variants > 0, "No dialog variants found for category: " + alias_suffix );

for( i = 0; i {
self.sound_dialog[ alias_suffix ][ i ] = i;
}

self.sound_dialog_available[ alias_suffix ] = [];
}

if ( self.sound_dialog_available[ alias_suffix ].size {
self.sound_dialog_available[ alias_suffix ] = self.sound_dialog[ alias_suffix ];
}

variation = random( self.sound_dialog_available[ alias_suffix ] );
self.sound_dialog_available[ alias_suffix ] = array_remove( self.sound_dialog_available[ alias_suffix ], variation );

if( IsDefined( force_variant ) )
{
variation = force_variant;
}

sound_to_play = alias_suffix + "_" + variation;

self thread do_player_playvox( prefix, index, sound_to_play, waittime, category, type );
}

do_player_playvox( prefix, index, sound_to_play, waittime, category, type )
{
if( !IsDefined( level.player_is_speaking ) )
{
level.player_is_speaking = 0;
}
if( level.player_is_speaking != 1 )
{
level.player_is_speaking = 1;
self playsound( prefix + sound_to_play, "sound_done" + sound_to_play );
self waittill( "sound_done" + sound_to_play );
wait( waittime );
level.player_is_speaking = 0;
if( isdefined( level.plr_vox[category][type + "_response"] ) )
{
level thread setup_response_line( self, index, category, type );
}
}
}

setup_response_line( player, index, category, type )
{
Dempsey = 0;
Nikolai = 1;
Takeo = 2;
Richtofen = 3;

switch( index )
{
case 0:
level setup_hero_rival( player, Takeo, Richtofen, category, type );
break;

case 1:
level setup_hero_rival( player, Richtofen, Takeo, category, type );
break;

case 2:
level setup_hero_rival( player, Dempsey, Nikolai, category, type );
break;

case 3:
level setup_hero_rival( player, Nikolai, Dempsey, category, type );
break;
}
return;
}

setup_hero_rival( player, hero, rival, category, type )
{
players = getplayers();

playHero = isdefined(players[hero]);
playRival = isdefined(players[rival]);

if(playHero && playRival)
{
if(randomfloatrange(0,1) {
playRival = false;
}
else
{
playHero = false;
}
}
if( playHero )
{
if( distancesquared (player.origin, players[hero].origin) {
players[hero] create_and_play_dialog( category, type + "_response", "hr_" );
}
else if( isdefined( players[rival] ) )
{
playRival = true;
}
}
if( playRival )
{
if( distancesquared (player.origin, players[rival].origin) {
players[rival] create_and_play_dialog( category, type + "_response", "riv_" );
}
}
}

//For any 2d Announcer Line
do_announcer_playvox( category )
{
if( !IsDefined( category ) )
return;

if( !IsDefined( level.devil_is_speaking ) )
{
level.devil_is_speaking = 0;
}

alias = level.devil_vox["prefix"] + category;

if( level.devil_is_speaking == 0 )
{
level.devil_is_speaking = 1;
level play_sound_2D( alias );
wait 2.0;
level.devil_is_speaking =0;
}
}

//** Player Killstreaks: The following functions start a timer on each player whenever they begin killing zombies.
//** If they kill a certain amount of zombies within a certain time, they will get a Killstreak line
player_killstreak_timer()
{
self endon("disconnect");
self endon("death");

if(getdvar ("zombie_kills") == "")
{
setdvar ("zombie_kills", "7");
}
if(getdvar ("zombie_kill_timer") == "")
{
setdvar ("zombie_kill_timer", "5");
}

kills = GetDvarInt( #"zombie_kills");
time = GetDvarInt( #"zombie_kill_timer");

if (!isdefined (self.timerIsrunning))
{
self.timerIsrunning = 0;
}

while(1)
{
self waittill("zom_kill");
self.killcounter ++;

if (self.timerIsrunning != 1)
{
self.timerIsrunning = 1;
self thread timer_actual(kills, time);
}
}
}

player_zombie_kill_vox( hit_location, player, mod, zombie )
{
weapon = player GetCurrentWeapon();
dist = DistanceSquared( player.origin, zombie.origin );

if( !isdefined(level.zombie_vars["zombie_insta_kill"] ) )
level.zombie_vars["zombie_insta_kill"] = 0;

instakill = level.zombie_vars["zombie_insta_kill"];

death = get_mod_type( hit_location, mod, weapon, zombie, instakill, dist );
chance = get_mod_chance( death );

if( chance > RandomIntRange( 1, 100 ) )
{
player create_and_play_dialog( "kill", death );
}
}

get_mod_chance( meansofdeath )
{
chance = undefined;

switch( meansofdeath )
{
case "melee": chance = 75; break;
case "melee_instakill": chance = 99; break;
case "weapon_instakill": chance = 10; break;
case "explosive": chance = 60; break;
case "flame": chance = 60; break;
case "raygun": chance = 75; break;
case "headshot": chance = 99; break;
case "crawler": chance = 30; break;
case "quad": chance = 30; break;
case "closekill": chance = 15; break;
case "bullet": chance = 10; break;
case "default": chance = 10; break;
}
return chance;
}

get_mod_type( impact, mod, weapon, zombie, instakill, dist )
{
close_dist = 64 * 64;
far_dist = 400 * 400;

//MELEE & MELEE_INSTAKILL
if( ( mod == "MOD_MELEE" ||
mod == "MOD_BAYONET" ||
mod == "MOD_UNKNOWN" ) &&
dist {
if( !instakill )
return "melee";
else
return "melee_instakill";
}

//EXPLOSIVE & EXPLOSIVE_INSTAKILL
if( ( mod == "MOD_GRENADE" ||
mod == "MOD_GRENADE_SPLASH" ||
mod == "MOD_PROJECTILE_SPLASH" ||
mod == "MOD_EXPLOSIVE" ) &&
weapon != "ray_gun_zm" )
{
if( !instakill )
return "explosive";
else
return "weapon_instakill";
}

//FLAME & FLAME_INSTAKILL
if( ( IsSubStr( weapon, "flame" ) ||
IsSubStr( weapon, "molotov_" ) ||
IsSubStr( weapon, "napalmblob_" ) ) &&
( mod == "MOD_BURNED" ||
mod == "MOD_GRENADE" ||
mod == "MOD_GRENADE_SPLASH" ) )
{
if( !instakill )
return "flame";
else
return "weapon_instakill";
}

//RAYGUN & RAYGUN_INSTAKILL
if( weapon == "ray_gun_zm" &&
dist > far_dist )
{
if( !instakill )
return "raygun";
else
return "weapon_instakill";
}

//HEADSHOT
if( ( mod == "MOD_RIFLE_BULLET" ||
mod == "MOD_PISTOL_BULLET" ) &&
( impact == "head" &&
dist > far_dist &&
!instakill ) )
{
return "headshot";
}

//QUAD
if( mod != "MOD_MELEE" &&
impact != "head" &&
zombie.animname == "quad_zombie" &&
!instakill )
{
return "quad";
}

//CRAWLER
if( mod != "MOD_MELEE" &&
impact != "head" &&
!zombie.has_legs &&
!instakill )
{
return "crawler";
}

//CLOSEKILL
if( mod != "MOD_BURNED" &&
dist !instakill )
{
return "closekill";
}

//BULLET & BULLET_INSTAKILL
if( mod == "MOD_RIFLE_BULLET" ||
mod == "MOD_PISTOL_BULLET" )
{
if( !instakill )
return "bullet";
else
return "weapon_instakill";
}

return "default";
}

timer_actual(kills, time)
{
self endon("disconnect");
self endon("death");

timer = gettime() + (time * 1000);
while(getTime() {
if (self.killcounter > kills)
{
self create_and_play_dialog( "kill", "streak" );

wait(1);

//resets the killcounter and the timer
self.killcounter = 0;

timer = -1;
}
wait(0.1);
}
self.killcounter = 0;
self.timerIsrunning = 0;
}

perks_a_cola_jingle_timer()
{
self thread play_random_broken_sounds();
while(1)
{
//wait(randomfloatrange(60, 120));
wait(randomfloatrange(31,45));
if(randomint(100) {
self thread play_jingle_or_stinger(self.script_sound);

}
}
}

play_jingle_or_stinger( perksacola )
{
playsoundatposition ("evt_electrical_surge", self.origin);
if(!IsDefined (self.jingle_is_playing ))
{
self.jingle_is_playing = 0;
}
if (IsDefined ( perksacola ))
{
if(self.jingle_is_playing == 0 && level.music_override == false)
{
self.jingle_is_playing = 1;
self playsound ( perksacola, "sound_done");
self waittill ("sound_done");
self.jingle_is_playing = 0;
}
}
}

play_random_broken_sounds()
{
level endon ("jingle_playing");
if (!isdefined (self.script_sound))
{
self.script_sound = "null";
}
if (self.script_sound == "mus_perks_revive_jingle")
{
while(1)
{
wait(randomfloatrange(7, 18));
playsoundatposition ("zmb_perks_broken_jingle", self.origin);
//playfx (level._effect["electric_short_oneshot"], self.origin);
playsoundatposition ("evt_electrical_surge", self.origin);

}
}
else
{
while(1)
{
wait(randomfloatrange(7, 18));
// playfx (level._effect["electric_short_oneshot"], self.origin);
playsoundatposition ("evt_electrical_surge", self.origin);
}
}
}

//SELF = Player Buying Perk
perk_vox( perk )
{
//Delay to prevent an early speech
wait( 1.5 );
if( !IsDefined( level.plr_vox["perk"][perk] ) )
{
/#
IPrintLnBold( perk + " has no PLR VOX category set up." );
#/
return;
}
self create_and_play_dialog( "perk", perk );
}

dialog_debugger( category, type )
{
/#
PrintLn( "DIALOG DEBUGGER: Category - " + category + " Type - " + type + " Response - " + type + "_response" );

if( !IsDefined( level.plr_vox[category][type] ) )
{
IPrintLnBold( "Player tried to play a line, but no alias exists. Category: " + category + " Type: " + type );
PrintLn( "DIALOG DEBUGGER ERROR: Alias Not Defined For " + category + " " + type );
}

if( !IsDefined( level.plr_vox[category][type + "_response" ] ) )
PrintLn( "DIALOG DEBUGGER ERROR: Response Alias Not Defined For " + category + " " + type + "_response" );
#/
}

//MUSIC STATES
init_music_states()
{
level.music_override = false;
level.music_round_override = false;

level.zmb_music_states = [];
level.zmb_music_states["round_start"] = spawnStruct();
level.zmb_music_states["round_start"].music = "mus_zombie_round_start";
level.zmb_music_states["round_start"].is_alias = true;
level.zmb_music_states["round_start"].override = true;
level.zmb_music_states["round_start"].round_override = true;
level.zmb_music_states["round_start"].musicstate = "WAVE";
level.zmb_music_states["round_end"] = spawnStruct();
level.zmb_music_states["round_end"].music = "mus_zombie_round_over";
level.zmb_music_states["round_end"].is_alias = true;
level.zmb_music_states["round_end"].override = true;
level.zmb_music_states["round_end"].round_override = true;
level.zmb_music_states["round_end"].musicstate = "SILENCE";
level.zmb_music_states["wave_loop"] = spawnStruct();
level.zmb_music_states["wave_loop"].music = "WAVE";
level.zmb_music_states["wave_loop"].is_alias = false;
level.zmb_music_states["wave_loop"].override = true;
level.zmb_music_states["game_over"] = spawnStruct();
level.zmb_music_states["game_over"].music = "mus_zombie_game_over";
level.zmb_music_states["game_over"].is_alias = true;
level.zmb_music_states["game_over"].override = false;
level.zmb_music_states["game_over"].musicstate = "SILENCE";
level.zmb_music_states["dog_start"] = spawnStruct();
level.zmb_music_states["dog_start"].music = "mus_zombie_dog_start";
level.zmb_music_states["dog_start"].is_alias = true;
level.zmb_music_states["dog_start"].override = true;
level.zmb_music_states["dog_end"] = spawnStruct();
level.zmb_music_states["dog_end"].music = "mus_zombie_dog_end";
level.zmb_music_states["dog_end"].is_alias = true;
level.zmb_music_states["dog_end"].override = true;
level.zmb_music_states["egg"] = spawnStruct();
level.zmb_music_states["egg"].music = "EGG";
level.zmb_music_states["egg"].is_alias = false;
level.zmb_music_states["egg"].override = false;
level.zmb_music_states["egg_safe"] = spawnStruct();
level.zmb_music_states["egg_safe"].music = "EGG_SAFE";
level.zmb_music_states["egg_safe"].is_alias = false;
level.zmb_music_states["egg_safe"].override = false;
}

change_zombie_music( state )
{
wait(.05);

m = level.zmb_music_states[state];

if( !IsDefined( m ) )
{
/#
IPrintLnBold( "Called change_zombie_music on undefined state: " + state );
#/
return;
}

if( !IsDefined( m.round_override ) )
m.round_override = false;

if( m.override == true && level.music_override == true )
return;

if( m.round_override == true && level.music_round_override == true )
return;

if( m.is_alias )
{
if( IsDefined( m.musicstate ) )
setmusicstate( m.musicstate );

play_sound_2d( m.music );
}
else
{
setmusicstate( m.music );
}
}
Zombiemode_aiturret
#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;

init()
{
level.auto_turret_array = GetEntArray( "auto_turret_trigger", "script_noteworthy" );

if( !isDefined( level.auto_turret_array ) )
{
return;
}
else if( level.mutators["mutator_noTraps"] )
{
for( i = 0; i {
level.auto_turret_array[i] disable_trigger();
}
}

level.curr_auto_turrets_active = 0;

if( !isDefined( level.max_auto_turrets_active ) )
{
level.max_auto_turrets_active = 2;
}

if( !isDefined( level.auto_turret_cost ) )
{
level.auto_turret_cost = 1500;
}

if( !isDefined( level.auto_turret_timeout ) )
{
level.auto_turret_timeout = 30;
}

for( i = 0; i {
level.auto_turret_array[i] SetCursorHint( "HINT_NOICON" );
level.auto_turret_array[i] sethintstring( &"ZOMBIE_NEED_POWER" );
level.auto_turret_array[i] UseTriggerRequireLookAt();
level.auto_turret_array[i].curr_time = -1;
level.auto_turret_array[i].turret_active = false;
level.auto_turret_array[i] thread auto_turret_think();
}
}

auto_turret_think()
{
if( !isDefined( self.target ) )
{
return;
}

turret_array = GetEntArray( self.target, "targetname" );

if(IsDefined(self.target))
{
for(i=0;i {
if(turret_array[i].model == "zombie_zapper_handle")
{
self.handle = turret_array[i];
}
else if(turret_array[i].classname == "misc_turret")
{
self.turret = turret_array[i];
}
}
}

self.turret SetDefaultDropPitch( -35 );

if( !isDefined( self.turret ) )
{
return;
}

self.turret SetConvergenceTime( 0.3 );
self.turret SetTurretTeam( "allies" );
self.turret MakeTurretUnusable();

self.audio_origin = self.origin;

flag_wait("power_on");


for( ;; )
{
cost = level.auto_turret_cost;
self SetHintString( &"ZOMBIE_AUTO_TURRET", cost );
// self thread add_teampot_icon();

self waittill( "trigger", player );
index = maps\_zombiemode_weapons::get_player_index(player);

if (player maps\_laststand::player_is_in_laststand() )
{
continue;
}

if(player in_revive_trigger())
{
continue;
}

//players = get_players();
// if ( (players.size == 1 && player.score // (players.size > 1 && level.team_pool[player.team_num].score if(player.score {
//player iprintln( "Not enough points to buy Perk: " + perk );
self playsound("deny");
player thread play_no_money_turret_dialog();
continue;
}

// if ( players.size == 1 )
{
player maps\_zombiemode_score::minus_to_player_score( cost );
}
/* else
{
player maps\_zombiemode_score::minus_to_team_score( cost );
} */

bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type autoturret", player.playername, player.score, level.team_pool[ player.team_num ].score, level.round_number, cost, self.target, self.origin );

self thread auto_turret_activate();
self PlaySound( "zmb_turret_startup" );

self disable_trigger();

self waittill( "turret_deactivated" );

playsoundatposition( "zmb_turret_down", self.audio_origin );

self enable_trigger();
}
}


activate_move_handle()
{
if(IsDefined(self.handle))
{
// Rotate switch model
self.handle rotatepitch( 160, .5 );
self.handle playsound( "amb_sparks_l_b" );
self.handle waittill( "rotatedone" );

self notify( "switch_activated" );
self waittill( "turret_deactivated" );

self.handle rotatepitch( -160, .5 );
}
}

play_no_money_turret_dialog()
{

}

auto_turret_activate()
{
self endon( "turret_deactivated" );

self thread activate_move_handle();
self waittill( "switch_activated" );

if( level.max_auto_turrets_active {
return;
}

while( level.curr_auto_turrets_active >= level.max_auto_turrets_active )
{
worst_turret = undefined;
worst_turret_time = -1;
for( i = 0; i {
if( level.auto_turret_array[i] == self )
{
continue;
}

if( !level.auto_turret_array[i].turret_active )
{
continue;
}

if( worst_turret_time {
worst_turret = level.auto_turret_array[i];
worst_turret_time = level.auto_turret_array[i].curr_time;
}
}
if( isDefined( worst_turret ) )
{
worst_turret auto_turret_deactivate();
}
else
{
assertex( false, "Couldn't free an auto turret to activate another, this should never be the case" );
}
}

self.turret SetMode( "auto_nonai" );
self.turret thread maps\_mgturret::burst_fire_unmanned();
self.turret_active = true;

self.turret_fx = Spawn( "script_model", self.turret.origin );
self.turret_fx SetModel( "tag_origin" );
self.turret_fx.angles = self.turret.angles;
PlayFxOnTag( level._effect["auto_turret_light"], self.turret_fx, "tag_origin" );

self.curr_time = level.auto_turret_timeout;

self thread auto_turret_update_timeout();

wait( level.auto_turret_timeout );

self auto_turret_deactivate();
}

auto_turret_deactivate()
{
self.turret_active = false;
self.curr_time = -1;
self.turret SetMode( "auto_ai" );
self.turret notify( "stop_burst_fire_unmanned" );

self.turret_fx delete();

self notify( "turret_deactivated" );
}

auto_turret_update_timeout()
{
self endon( "turret_deactivated" );

while( self.curr_time > 0 )
{
wait( 1 );
self.curr_time--;
}
}

Link to comment

Zombiemode_Blockers (in 2 parts)

#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#using_animtree( "generic_human" );

//
//
//
init()
{
//////////////////////////////////////////////////////////////////////////////////////
//
// Zombie Window and Blockers speaks between two main scripts _zombiemode_blockers
// and _zombiemode_spawner and _zombimode _utility
//
//
//
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////////////////


init_blockers();

// level thread rebuild_barrier_think();

//////////////////////////////////////////
//designed by prod
//set_zombie_var( "rebuild_barrier_cap_per_round", 500 );
//////////////////////////////////////////
}


//
// BLOCKERS
//
init_blockers()
{
// EXTERIOR BLOCKERS ----------------------------------------------------------------- //
level.exterior_goals = getstructarray( "exterior_goal", "targetname" );

for( i = 0; i {
level.exterior_goals[i] thread blocker_init();
}

// DOORS ----------------------------------------------------------------------------- //
zombie_doors = GetEntArray( "zombie_door", "targetname" );

for( i = 0; i {
zombie_doors[i] thread door_init();
}

// DEBRIS ---------------------------------------------------------------------------- //
zombie_debris = GetEntArray( "zombie_debris", "targetname" );

for( i = 0; i {
zombie_debris[i] thread debris_init();
}

// Flag Blockers ---------------------------------------------------------------------- //
flag_blockers = GetEntArray( "flag_blocker", "targetname" );

for( i = 0; i {
flag_blockers[i] thread flag_blocker();
}

// SHUTTERS --------------------------------------------------------------------------- //
window_shutter = GetEntArray( "window_shutter", "targetname" );

for( i = 0; i {
window_shutter[i] thread shutter_init();
}
}


//
// DOORS --------------------------------------------------------------------------------- //
//
door_init()
{
self.type = undefined;

// Figure out what kind of door we are
targets = GetEntArray( self.target, "targetname" );

//CHRIS_P - added script_flag support for doors as well
if( isDefined(self.script_flag) && !IsDefined( level.flag[self.script_flag] ) )
{
// Initialize any flags called
if( IsDefined( self.script_flag ) )
{
tokens = Strtok( self.script_flag, "," );
for ( i=0; i {
flag_init( self.script_flag );
}
}

}

// Door trigger types
if ( !IsDefined( self.script_noteworthy ) )
{
self.script_noteworthy = "default";
}

//MM Consolidate type codes for each door into script_string
self.doors = [];
for(i=0;i {
targets[i] door_classify( self );
}

//AssertEx( IsDefined( self.type ), "You must determine how this door opens. Specify script_angles, script_vector, or a script_noteworthy... Door at: " + self.origin );
cost = 1000;
if( IsDefined( self.zombie_cost ) )
{
cost = self.zombie_cost;
}

self SetCursorHint( "HINT_NOICON" );

// MM (03/09/10) - Allow activation at any time in order to make it easier to open bigger doors.
// self UseTriggerRequireLookAt();
self thread door_think();

// MM - Added support for electric doors. Don't have to add them to level scripts
if ( IsDefined( self.script_noteworthy ) )
{
if ( self.script_noteworthy == "electric_door" || self.script_noteworthy == "electric_buyable_door" )
{
self sethintstring(&"ZOMBIE_NEED_POWER");
// self set_door_unusable();
if( isDefined( level.door_dialog_function ) )
{
self thread [[ level.door_dialog_function ]]();
}
return;
}
else if ( self.script_noteworthy == "kill_counter_door" )
{
self sethintstring(&"ZOMBIE_DOOR_ACTIVATE_COUNTER", cost);
// self thread add_teampot_icon();
return;
}
}

self set_hint_string( self, "default_buy_door_" + cost );
// self thread add_teampot_icon();
}


//
// Help fix-up doors not using script_string and also to reclassify non-door entities.
//
door_classify( parent_trig )
{
if ( IsDefined(self.script_noteworthy) && self.script_noteworthy == "clip" )
{
parent_trig.clip = self;
parent_trig.script_string = "clip";
}
else if( !IsDefined( self.script_string ) )
{
if( IsDefined( self.script_angles ) )
{
self.script_string = "rotate";
}
else if( IsDefined( self.script_vector ) )
{
self.script_string = "move";
}
}
else
{
if ( !IsDefined( self.script_string ) )
{
self.script_string = "";
}

// Handle other script_strings here
switch( self.script_string )
{
case "anim":
AssertEx( IsDefined( self.script_animname ), "Blocker_init: You must specify a script_animname for "+self.targetname );
AssertEx( IsDefined( level.scr_anim[ self.script_animname ] ), "Blocker_init: You must define a level.scr_anim for script_anim -> "+self.script_animname );
AssertEx( IsDefined( level.blocker_anim_func ), "Blocker_init: You must define a level.blocker_anim_func" );
break;

case "counter_1s":
parent_trig.counter_1s = self;
return; // this is not a door element

case "counter_10s":
parent_trig.counter_10s = self;
return; // this is not a door element

case "counter_100s":
parent_trig.counter_100s = self;
return; // this is not a door element

case "explosives":
if ( !IsDefined(parent_trig.explosives) )
{
parent_trig.explosives = [];
}
parent_trig.explosives[parent_trig.explosives.size] = self;
return; // this is not a door element
}
}

if ( self.classname == "script_brushmodel" )
{
self DisconnectPaths();
}
parent_trig.doors[parent_trig.doors.size] = self;
}


//
// Someone just tried to buy the door
// return true if door was bought
// NOTE: This is currently intended to be used as a non-threaded call
// self is a door trigger
door_buy()
{
self waittill( "trigger", who );

if( !who UseButtonPressed() )
{
return false;
}

if( who in_revive_trigger() )
{
return false;
}

if( is_player_valid( who ) )
{
players = get_players();
// No pools in solo game
if ( players.size == 1 && who.score >= self.zombie_cost )
{
// solo buy
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost );
}
else if( level.team_pool[ who.team_num ].score >= self.zombie_cost )
{
// team buy
who maps\_zombiemode_score::minus_to_team_score( self.zombie_cost );
}
else if( level.team_pool[ who.team_num ].score + who.score >= self.zombie_cost )
{
// team funds + player funds
team_points = level.team_pool[ who.team_num ].score;
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost - team_points );
who maps\_zombiemode_score::minus_to_team_score( team_points );
}
else // Not enough money
{
play_sound_at_pos( "no_purchase", self.doors[0].origin );
who maps\_zombiemode_audio::create_and_play_dialog( "general", "door_deny", undefined, 0 );
return false;
}

// buy the thing
bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type door", who.playername, who.score, level.team_pool[ who.team_num ].score, level.round_number, self.zombie_cost, self.script_flag, self.origin );
}

return true;
}


//
// Open a delay door once the time has expired
// self is a door
door_delay()
{
// Show explosives
if ( IsDefined( self.explosives ) )
{
for ( i=0; i {
self.explosives[i] Show();
}
}

// Now wait
if (!IsDefined(self.script_int) )
{
self.script_int = 5;
}

// Turn off the triggers.
all_trigs = getentarray( self.target, "target" );
for( i = 0; i {
all_trigs[i] trigger_off();
}

wait (self.script_int);
for ( i=0; i {
/#
iprintln( self.script_int - i );
#/
wait(1);
}

// Time's Up!
// Show explosives
if ( IsDefined( self.explosives ) )
{
for ( i=0; i {
PlayFX( level._effect["def_explosion"], self.explosives[i].origin, AnglesToForward(self.explosives[i].angles) );
self.explosives[i] Hide();
}
}
}


//
// Initialize the countdown
//
kill_countdown()
{
kills_remaining = self.kill_goal - level.total_zombies_killed;

// Play initiate sound
players = GetPlayers();
for (i=0; i {
players[i] playlocalsound( "zmb_laugh_child" );
}

// Random number flipping to setup the counter
level.kill_counter_hud FadeOverTime( 1.0 );
level.kill_counter_hud.alpha = 1;

// Note: First 2 stages will be number flipping
num_stages = 3; // Only 1 digit counter
if ( IsDefined( self.counter_10s ) )
{
num_stages = 4; // 2-digit
}
else
{
num_stages = 5; // 3-digit
}

time_per_stage = 1.0; // how long to take for each phase
steps = time_per_stage * num_stages / 0.1; // 0.1 is the interval
steps_per_stage = steps / num_stages;
stage_num = 1;
ones = 0;
tens = 0;
hundreds = 0;

for (i=0; i {
if ( i > steps_per_stage * stage_num )
{
stage_num++;
}

// 1s
if ( num_stages - stage_num == 0 )
{
ones = kills_remaining % 10;
}
else
{
ones = i % 10;
}
self.counter_1s set_counter( ones );

// 10s
if ( IsDefined( self.counter_10s ) )
{
if ( num_stages - stage_num {
tens = int( kills_remaining / 10 );
}
else
{
tens = i % 10;
}
self.counter_10s set_counter( tens );
}

if ( IsDefined( self.counter_100s ) )
{
if ( num_stages - stage_num {
hundreds = int( kills_remaining / 100 );
}
else
{
hundreds = i % 10;
}
self.counter_100s set_counter( hundreds );
}

level.kill_counter_hud SetValue( hundreds*100 + tens*10 + ones );
wait (0.1);
}


level.kill_counter_hud FadeOverTime( 1.0 );
level.kill_counter_hud.color = ( 0.21, 0, 0 );

// Now keep track of how many kills are needed
while ( level.total_zombies_killed {
kills_remaining = self.kill_goal - level.total_zombies_killed;
self.counter_1s set_counter( kills_remaining % 10 );
if ( IsDefined( self.counter_10s ) )
{
self.counter_10s set_counter( int( kills_remaining / 10 ) );
}
if ( IsDefined( self.counter_100s ) )
{
self.counter_100s set_counter( int( kills_remaining / 100 ) );
}
level.kill_counter_hud SetValue( kills_remaining );

level waittill( "zom_kill" );
}

// Zero! Play end sound
players = GetPlayers();
for (i=0; i {
players[i] playlocalsound( "zmb_perks_packa_ready" );
}

self.counter_1s set_counter( 0 );
if ( IsDefined( self.counter_10s ) )
{
self.counter_10s set_counter( 0 );
}
if ( IsDefined( self.counter_100s ) )
{
self.counter_100s set_counter( 0 );
}
level.kill_counter_hud SetValue( 0 );
wait(1.0);

self notify( "countdown_finished" );
}

//
// Open a delay door once the time has expired
// self is a door
door_kill_counter()
{
// flag_wait( "all_players_connected" );

// init the counter
counter = 0;
if (!IsDefined(self.script_int) )
{
counter = 5;
}
else
{
counter = self.script_int;

// formula for reducing the kills needed by number of players
players = GetPlayers();
if ( players.size {
// Reduce it by 20% per person under three players
fraction = int( counter * 0.2 );
counter -= fraction * (4 - players.size );
}
}
// Now randomize between that and +20%.
counter = RandomIntRange( counter, Int(counter * 1.2)+1 );

/#
if( GetDvarInt( #"zombie_cheat" ) >= 1 )
{
counter = 0;
}
#/

AssertEx( IsDefined( self.counter_1s ), "Door Kill counter needs a 'ones' digit model" );
AssertEx( (counter AssertEx( (counter
// Setup the Hud display
level.kill_counter_hud = create_counter_hud();

// Show explosives
// if ( IsDefined( self.explosives ) )
// {
// for ( i=0; i // {
// self.explosives[i] Show();
// }
// }
// self waittill( "trigger", who );

num_enemies = get_enemy_count();
if ( level.zombie_total + num_enemies {
level.zombie_total += counter - num_enemies;
}

// Turn off the triggers.
all_trigs = getentarray( self.target, "target" );
for( i = 0; i {
all_trigs[i] trigger_off();
}

// Now do the countdown
self.kill_goal = level.total_zombies_killed + counter;
self thread kill_countdown();

self waittill( "countdown_finished" );

level.kill_counter_hud destroy_hud();

// Goal reached! BOOM!
self.counter_1s Delete();
if ( IsDefined( self.counter_10s ) )
{
self.counter_10s Delete();
}
if ( IsDefined( self.counter_100s ) )
{
self.counter_100s Delete();
}
if ( IsDefined( self.explosives ) )
{
for ( i=0; i {
self.explosives[i] Hide();
}
PlayFX( level._effect["betty_explode"], self.explosives[0].origin, AnglesToForward(self.explosives[0].angles) );

self.explosives[0] playsound( "mpl_kls_artillery_impact" );
}
}


//
// Make the door do its thing
// self is a door
// open: true makes the door open, false makes it close (reverse operation). Defaults to TRUE
// NOTE: open is currently ONLY supported for "move" type doors
// time is a time override
door_activate( time, open )
{
if ( !IsDefined(time) )
{
time = 1;
if( IsDefined( self.script_transition_time ) )
{
time = self.script_transition_time;
}
}

if ( !IsDefined( open ) )
{
open = true;
}

self NotSolid();

if(self.classname == "script_brushmodel")
{
if ( open )
{
self ConnectPaths();
}
}

// Prevent multiple triggers from making doors move more than once
if ( IsDefined(self.door_moving) )
{
return;
}
self.door_moving = 1;

if ( ( IsDefined( self.script_noteworthy ) && self.script_noteworthy == "clip" ) ||
( IsDefined( self.script_string ) && self.script_string == "clip" ) )
{
return;
}

if ( IsDefined( self.script_sound ) )
{
play_sound_at_pos( self.script_sound, self.origin );
}
else
{
play_sound_at_pos( "door_slide_open", self.origin );
}

// scale
scale = 1;
if ( !open )
{
scale = -1;
}

// MM - each door can now have a different opening style instead of
// needing to be all the same
switch( self.script_string )
{
case "rotate":
if(isDefined(self.script_angles))
{
self RotateTo( self.script_angles, time, 0, 0 );
self thread door_solid_thread();
}
wait(randomfloat(.15));
break;
case "move":
case "slide_apart":
if(isDefined(self.script_vector))
{
vector = vector_scale( self.script_vector, scale );
if ( time >= 0.5 )
{
self MoveTo( self.origin + vector, time, time * 0.25, time * 0.25 );
}
else
{
self MoveTo( self.origin + vector, time );
}
self thread door_solid_thread();
if ( !open )
{
self thread disconnect_paths_when_done();
}
}
wait(randomfloat(.15));
break;

case "anim":
// self animscripted( "door_anim", self.origin, self.angles, level.scr_anim[ self.script_animname ] );
self [[ level.blocker_anim_func ]]( self.script_animname );
self thread door_solid_thread_anim();
wait(randomfloat(.15));
break;

case "physics":
self thread physics_launch_door( self );
wait(0.10);
break;
}

//Chris_P - just in case spawners are targeted
// if( isDefined( self.target ) )
// {
// // door needs to target new spawners which will become part
// // of the level enemy array
// self add_new_zombie_spawners();
// }
}


//
// Wait to be opened!
// self is a door trigger
door_think()
{
// maybe the door the should just bust open instead of slowly opening.
// maybe just destroy the door, could be two players from opposite sides..
// breaking into chunks seems best.
// or I cuold just give it no collision

cost = 1000;
if( IsDefined( self.zombie_cost ) )
{
cost = self.zombie_cost;
}

while( 1 )
{
switch( self.script_noteworthy )
{
case "electric_door":
flag_wait( "power_on" );
break;

case "electric_buyable_door":
flag_wait( "power_on" );

self set_hint_string( self, "default_buy_door_" + cost );
// self thread add_teampot_icon();
// self UseTriggerRequireLookAt();

if ( !self door_buy() )
{
continue;
}
break;

case "delay_door": // set timer and explode
if ( !self door_buy() )
{
continue;
}

self door_delay( cost );
break;

case "kill_counter_door":
if ( !self door_buy() )
{
continue;
}

self door_kill_counter();
break;

default:
if ( !self door_buy() )
{
continue;
}
break;
}
// if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_door")
// {
// flag_wait( "power_on" );
// }
// else if(isDefined(self.script_noteworthy) && self.script_noteworthy == "electric_buyable_door")
// {
// flag_wait( "power_on" );
//
// self set_hint_string( self, "default_buy_door_" + cost );
// self SetCursorHint( "HINT_NOICON" );
// self UseTriggerRequireLookAt();
//
// self waittill( "trigger", who );
//
// self door_buy();
// }
// else
// {
// self waittill( "trigger", who );
//
// self door_buy();
// }


// Door has been activated, make it do its thing
for(i=0;i {
// Don't thread this so the doors don't move at once
self.doors[i] door_activate();
}
// Just play purchase sound on the first door
if( self.doors.size )
{
play_sound_at_pos( "purchase", self.doors[0].origin );
}


// Set any flags called
if( IsDefined( self.script_flag ) )
{
tokens = Strtok( self.script_flag, "," );
for ( i=0; i {
flag_set( tokens[i] );
}
}

// get all trigs for the door, we might want a trigger on both sides
// of some junk sometimes
all_trigs = getentarray( self.target, "target" );
for( i = 0; i {
all_trigs[i] trigger_off();
}
break;
}
}


//
// Launch the door!
// self = door entity
// door_trig = door trigger
physics_launch_door( door_trig )
{
// origin = self.origin;
// if ( IsDefined(door_trig.explosives) )
// {
// origin = door_trig.explosives[0].origin;
// }
//
vec = vector_scale( VectorNormalize( self.script_vector ), 5 );
self MoveTo( self.origin + vec, 0.1 );
self waittill( "movedone" );

self PhysicsLaunch( self.origin, self.script_vector *10 );
wait(0.1);
PhysicsExplosionSphere( vector_scale( vec, -1 ), 120, 1, 100 );

wait(60);

self delete();
}


//
// Waits until it is finished moving and then returns to solid once no player is touching it
// (So they don't get stuck). The door is made notSolid initially, otherwise, a player
// could block its movement or cause a player to become stuck.
// self is a door
door_solid_thread()
{
// MM - added support for movedone.
self waittill_either( "rotatedone", "movedone" );

self.door_moving = undefined;
while( 1 )
{
players = get_players();
player_touching = false;
for( i = 0; i {
if( players[i] IsTouching( self ) )
{
player_touching = true;
break;
}
}

if( !player_touching )
{
self Solid();
return;
}

wait( 1 );
}
}


//
// Called on doors using anims. It needs a different waittill,
// and expects the animname message to be the same as the one passed into scripted anim
// self is a door
door_solid_thread_anim( )
{
// MM - added support for movedone.
self waittillmatch( "door_anim", "end" );

self.door_moving = undefined;
while( 1 )
{
players = get_players();
player_touching = false;
for( i = 0; i {
if( players[i] IsTouching( self ) )
{
player_touching = true;
break;
}
}

if( !player_touching )
{
self Solid();
return;
}

wait( 1 );
}
}


//
//
//
disconnect_paths_when_done()
{
self waittill_either( "rotatedone", "movedone" );

self DisconnectPaths();
}

//
// DEBRIS - these are "doors" that consist of various pieces of piled objects
// they lift up and disappear when bought.
//
debris_init()
{
cost = 1000;
if( IsDefined( self.zombie_cost ) )
{
cost = self.zombie_cost;
}

self set_hint_string( self, "default_buy_debris_" + cost );
self setCursorHint( "HINT_NOICON" );

// self thread add_teampot_icon();

if( isdefined (self.script_flag) && !IsDefined( level.flag[self.script_flag] ) )
{
flag_init( self.script_flag );
}

// self UseTriggerRequireLookAt();
self thread debris_think();
}


//
// self is a debris trigger
//
debris_think()
{

if( isDefined( level.custom_debris_function ) )
{
self [[ level.custom_debris_function ]]();
}

while( 1 )
{
self waittill( "trigger", who );

if( !who UseButtonPressed() )
{
continue;
}

if( who in_revive_trigger() )
{
continue;
}

if( is_player_valid( who ) )
{
// Can we afford this door?
players = get_players();
if ( players.size == 1 && who.score >= self.zombie_cost )
{
// solo buy
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost );
}
else if( level.team_pool[ who.team_num ].score >= self.zombie_cost )
{
// team buy
who maps\_zombiemode_score::minus_to_team_score( self.zombie_cost );
}
else if( level.team_pool[ who.team_num ].score + who.score >= self.zombie_cost )
{
// team funds + player funds
team_points = level.team_pool[ who.team_num ].score;
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost - team_points );
who maps\_zombiemode_score::minus_to_team_score( team_points );
}
else
{
play_sound_at_pos( "no_purchase", self.origin );
who maps\_zombiemode_audio::create_and_play_dialog( "general", "door_deny", undefined, 1 );
continue;
}

// Okay remove the debris
bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type door", who.playername, who.score, level.team_pool[ who.team_num ].score, level.round_number, self.zombie_cost, self.script_flag, self.origin );

// delete the stuff
junk = getentarray( self.target, "targetname" );

// Set any flags called
if( IsDefined( self.script_flag ) )
{
tokens = Strtok( self.script_flag, "," );
for ( i=0; i {
flag_set( tokens[i] );
}
}

play_sound_at_pos( "purchase", self.origin );
level notify ("junk purchased");

move_ent = undefined;
clip = undefined;
for( i = 0; i {
junk[i] connectpaths();
// junk[i] add_new_zombie_spawners();

if( IsDefined( junk[i].script_noteworthy ) )
{
if( junk[i].script_noteworthy == "clip" )
{
clip = junk[i];
continue;
}
}

struct = undefined;
if( IsDefined( junk[i].script_linkTo ) )
{
struct = getstruct( junk[i].script_linkTo, "script_linkname" );
if( IsDefined( struct ) )
{
move_ent = junk[i];
junk[i] thread debris_move( struct );
}
else
{
junk[i] Delete();
}
}
else
{
junk[i] Delete();
}
}

// get all trigs, we might want a trigger on both sides
// of some junk sometimes
all_trigs = getentarray( self.target, "target" );
for( i = 0; i {
all_trigs[i] delete();
}

if( IsDefined( clip ) )
{
if( IsDefined( move_ent ) )
{
move_ent waittill( "movedone" );
}

clip Delete();
}

break;
}
}
}


//
// Moves the debris out of place
// self is a debris piece
//
debris_move( struct )
{
self script_delay();
//chrisp - prevent playerse from getting stuck on the stuff
self notsolid();

self play_sound_on_ent( "debris_move" );
playsoundatposition ("zmb_lightning_l", self.origin);
if( IsDefined( self.script_firefx ) )
{
PlayFX( level._effect[self.script_firefx], self.origin );
}

// Do a little jiggle, then move.
if( IsDefined( self.script_noteworthy ) )
{
if( self.script_noteworthy == "jiggle" )
{
num = RandomIntRange( 3, 5 );
og_angles = self.angles;
for( i = 0; i {
angles = og_angles + ( -5 + RandomFloat( 10 ), -5 + RandomFloat( 10 ), -5 + RandomFloat( 10 ) );
time = RandomFloatRange( 0.1, 0.4 );
self Rotateto( angles, time );
wait( time - 0.05 );
}
}
}

time = 0.5;
if( IsDefined( self.script_transition_time ) )
{
time = self.script_transition_time;
}

self MoveTo( struct.origin, time, time * 0.5 );
self RotateTo( struct.angles, time * 0.75 );

self waittill( "movedone" );

//Z2 commented out missing sound, wouldn't go past.
//self play_sound_on_entity("couch_slam");

if( IsDefined( self.script_fxid ) )
{
PlayFX( level._effect[self.script_fxid], self.origin );
playsoundatposition("zmb_zombie_spawn", self.origin); //just playing the zombie_spawn sound when it deletes the blocker because it matches the particle.
}

self Delete();

}


//
// BLOCKER (aka window, bar, board)
// Self = exterior_goal, it is the node that targets all of the boards and bars
// This sets up every window in level,
blocker_init()
{
if( !IsDefined( self.target ) ) // If the exterior_goal entity has no targets defined then return
{
return;
}

targets = GetEntArray( self.target, "targetname" ); // Grab all the pieces that are targeted by the exterior_goal

self.barrier_chunks = []; // self has a newly defined array of barrier_chunks

use_boards = true;

if( level.mutators["mutator_noBoards"] )
{
use_boards = false;
}

for( j = 0; j {
if( IsDefined( targets[j].script_noteworthy ) ) // If a script noteworthy is defined
{
if( targets[j].script_noteworthy == "clip" ) // Grab the clip and continue
{
self.clip = targets[j]; // self.clip is defined from the array
continue; // Go forward with the script
}
}

// jl/ jan/15/10 add new setup for grates
// I hide all the pieces you don't need to see right now.
// This works
// Now when they get pulled off, I just want them to swap out the model

if( IsDefined( targets[j].script_parameters ) ) // If a script noteworthy is defined
{
if( targets[j].script_parameters == "grate" )
{
if( IsDefined( targets[j].script_noteworthy ) ) // If a script noteworthy is defined
{
if( targets[j].script_noteworthy == "2" || targets[j].script_noteworthy == "3" || targets[j].script_noteworthy == "4" ||
targets[j].script_noteworthy == "5" || targets[j].script_noteworthy == "6")
{
// this is an improper setup because each piece is still sitting there
targets[j] Hide(); // this grabs all the pieces and hides it
/#
IPrintLnBold(" Hide ");
#/
}
}
}
//DCS: new pentagon system where barricade starts as new and is repaired with boards, etc.
// start with repair boards hidden.
else if( targets[j].script_parameters == "repair_board" )
{
targets[j].unbroken_section = GetEnt(targets[j].target,"targetname");
if(IsDefined(targets[j].unbroken_section))
{
targets[j].unbroken_section LinkTo(targets[j]);
targets[j] Hide();
targets[j] notSolid();
targets[j].unbroken = true;

// self is the goal (level.exterior_goals)
if(IsDefined(targets[j].unbroken_section.script_noteworthy) && targets[j].unbroken_section.script_noteworthy == "glass")
{
targets[j].material = "glass";
targets[j] thread destructible_glass_barricade(targets[j].unbroken_section, self);
}
else if(IsDefined(targets[j].unbroken_section.script_noteworthy) && targets[j].unbroken_section.script_noteworthy == "metal")
{
targets[j].material = "metal";
}
}
}
}

if( IsDefined ( targets[j].targetname ) )
{
if( targets[j].targetname == "auto2" )
{
// targets[j]
}
}

if( use_boards )
{
targets[j] update_states("repaired"); // Change state to repaired
targets[j].destroyed = false;
}
else
{
targets[j] update_states("destroyed");
targets[j].destroyed = true;
targets[j] Hide();
targets[j] notSolid();
}
targets[j].claimed = false;
targets[j].anim_grate_index = 0; // check this index to know where each piece is
// I can create another thing to track here if I need to
targets[j].og_origin = targets[j].origin; // This one piece's origin is defined by grabbing the starting origin
targets[j].og_angles = targets[j].angles; // The one piece's angles is defined by grabbing the starting angles
self.barrier_chunks[self.barrier_chunks.size] = targets[j]; // barrier_chunks is the total size of the bars windows or boards used

self blocker_attack_spots(); // exterior_goal thread
}

if( use_boards )
{
assert( IsDefined( self.clip ) );
self.trigger_location = getstruct( self.target, "targetname" ); // trigger_location is the new name for exterior_goal targets -- which is auto1 in all cases

self thread blocker_think(); // exterior_goal thread blocker_think
}
}


//-------------------------------------------------------------------------------
// DCS 090710: glass barricade. Player can damage.
// self is chunk, aka. repair_board
//-------------------------------------------------------------------------------
destructible_glass_barricade(unbroken_section, node)
{
unbroken_section SetCanDamage( true );
unbroken_section.health = 99999;
unbroken_section waittill( "damage", amount, who);
if( is_player_valid( who ) || who maps\_laststand::player_is_in_laststand())
{
self thread maps\_zombiemode_spawner::zombie_boardtear_offset_fx_horizontle( self, node );
level thread remove_chunk( self, node, true );
self update_states("destroyed");
self notify("destroyed");
self.unbroken = false;

}
}
//-------------------------------------------------------------------------------

// jl jan/05/10
// Self = exterior_goal, it is the node that targets all of the boards and bars
// Creates three spots that the AI can now choose from to attack the window
blocker_attack_spots()
{
// Get closest chunk
chunk = getClosest( self.origin, self.barrier_chunks ); // chunk = grab closest origin from array of barrier_chunks

dist = Distance2d( self.origin, chunk.origin ) - 36;
spots = [];
spots[0] = groundpos( self.origin + ( AnglesToForward( self.angles ) * dist ) + ( 0, 0, 60 ) );
spots[spots.size] = groundpos( spots[0] + ( AnglesToRight( self.angles ) * 28 ) + ( 0, 0, 60 ) );
spots[spots.size] = groundpos( spots[0] + ( AnglesToRight( self.angles ) * -28 ) + ( 0, 0, 60 ) );

taken = []; // new array
for( i = 0; i {
taken[i] = false;
}

self.attack_spots_taken = taken; // set attack_spots_taken to taken
self.attack_spots = spots; // set attack_spots to spots

self thread debug_attack_spots_taken(); // self = exterior_goal
}


// jl jan/05/10
// Self = exterior_goal, it is the node that targets all of the boards and bars
blocker_think()
{
while( 1 ) // exterior_goal is going to constantly loop
{
wait( 0.5 );

if( all_chunks_intact( self.barrier_chunks ) ) // speak to _zombiemode_utility and into all_chunks_intact function
{
// if any piece has the state of not repaired then return false
// if the board has been repaired then return true
continue;
}

if( no_valid_repairable_boards( self.barrier_chunks ) )// speak to _zombiemode_utility and into no_valid_repairable_boards function
{
// if any piece has been destroyed return false
// if any piece is not destroyed then return true
continue;
}

self blocker_trigger_think();
}
}


// Self = exterior_goal, it is the node that targets all of the boards and bars
// trigger_location
// this function repairs the boards
blocker_trigger_think()
{
// They don't cost, they now award the player the cost...
cost = 10;
if( IsDefined( self.zombie_cost ) )
{
cost = self.zombie_cost;
}

original_cost = cost;

radius = 96;
height = 96;

if( IsDefined( self.trigger_location ) ) // this is defined in the blocker_init function
{
trigger_location = self.trigger_location; // trigger_location is the new name for exterior_goal targets -- which is auto1 in all cases
}
else
{
trigger_location = self; // if it is not defined then just use self as the trigger_location
}

if( IsDefined( trigger_location.radius ) ) // he is asking if it is defined here, yet he never defines it anywhere
{
radius = trigger_location.radius;
}

if( IsDefined( trigger_location.height ) ) // he is asking if it is defined here, yet he never defines it anywhere
{
height = trigger_location.height;
}

trigger_pos = groundpos( trigger_location.origin ) + ( 0, 0, 4 ); // this is from trigger_location and is reset to trigger_pos
trigger = Spawn( "trigger_radius", trigger_pos, 0, radius, height ); // spawn in a trigger at the location of the exterior_goal
trigger thread trigger_delete_on_repair(); // This function waits till the boards/bars are repaired
/#
if( GetDvarInt( #"zombie_debug" ) > 0 ) //
{
thread debug_blocker( trigger_pos, radius, height );
}
#/

// Rebuilding no longer costs us money... It's rewarded

//////////////////////////////////////////
//designed by prod; NO reward hint (See DT#36173)
trigger set_hint_string( self, "default_reward_barrier_piece" ); // this is the string to call when the player is the trigger
//trigger thread blocker_doubler_hint( "default_reward_barrier_piece_", original_cost );
//////////////////////////////////////////

trigger SetCursorHint( "HINT_NOICON" );

while( 1 ) // the trigger constantly loops here till while the player interacts with it.
{
trigger waittill( "trigger", player );

if( player hasperk( "specialty_fastreload" ) )
{
has_perk = "specialty_fastreload";
}
//else if( player hasperk( "specialty_fastreload_upgrade" ) )
//{
// has_perk = "specialty_fastreload_upgrade";
//}
else
{
has_perk = undefined;
}

if( all_chunks_intact( self.barrier_chunks ) ) // barrier chunks are all the pieces targeted from the exterior_goal
{
// if any piece has the state of not repaired then return false
// if the board has been repaired then return true
trigger notify("all_boards_repaired");
return;
}

if( no_valid_repairable_boards( self.barrier_chunks ) ) // barrier chunks are all the pieces targeted from the exterior_goal
{
// if any piece has been destroyed return false
// if any piece is not destroyed then return true
trigger notify("no valid boards");
return;
}

players = GetPlayers();

while( 1 )
{
if( !player IsTouching( trigger ) )
{
break;
}

if( !is_player_valid( player ) )
{
break;
}

if( player in_revive_trigger() )
{
break;
}

if( players.size == 1 && IsDefined( players[0].intermission ) && players[0].intermission == 1)
{
break;
}


if( !player use_button_held() )
{
break;
}



chunk = get_random_destroyed_chunk( self.barrier_chunks ); // calls get_random_destroyed_chunk in _zombiemode_utility, continue if the chunk was destroyed

if(IsDefined(chunk.script_parameter) && chunk.script_parameters == "repair_board")
{
if(IsDefined(chunk.unbroken_section))
{
chunk Show();
chunk Solid();
chunk.unbroken_section self_delete();
}
}
else
{
chunk Show();
}



if ( !isDefined( chunk.script_parameters ) || chunk.script_parameters == "board" || chunk.script_parameters == "repair_board")
{
chunk play_sound_on_ent( "rebuild_barrier_piece" );
playsoundatposition ("zmb_cha_ching", (0,0,0));
}
else if ( chunk.script_parameters == "bar" )
{
chunk play_sound_on_ent( "rebuild_barrier_piece" );
playsoundatposition ("zmb_cha_ching", (0,0,0));
}

// I need to do this in a different place
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "bar" )
{
if(isdefined(chunk.script_noteworthy))
{
if(chunk.script_noteworthy == "5") // this is the far left , this bar now bends it does not leave
{
chunk hide();
}
else if(chunk.script_noteworthy == "3" )
{
chunk hide();
}
}
}
}


self thread replace_chunk( chunk, has_perk ); // writing out


assert( IsDefined( self.clip ) );
self.clip enable_trigger();
self.clip DisconnectPaths(); // the boards disconnect paths everytime they are used here

//maps\_zombiemode_challenges::doMissionCallback( "zm_board_repair", player );
bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type repair", player.playername, player.score, level.team_pool[ player.team_num ].score, level.round_number, original_cost, self.target, self.origin );

if( !self script_delay() )
{
wait( 1 );
}

if( !is_player_valid( player ) )
{
break;
}

// set the score
player.rebuild_barrier_reward += cost;
if( player.rebuild_barrier_reward {
player maps\_zombiemode_score::player_add_points( "rebuild_board", cost );
player play_sound_on_ent( "purchase" );

}
// general contractor achievement for dlc 2. keep track of how many board player repaired.
if(IsDefined(player.board_repair))
{
player.board_repair += 1;
}

if( all_chunks_intact( self.barrier_chunks ) ) // This calls into _zombiemode_utility
{
// if any piece has the state of not repaired then return false
// if the board has been repaired then return true
trigger notify("all_boards_repaired");
return;
}

if( no_valid_repairable_boards( self.barrier_chunks ) ) // This calls into _zombiemode_utility
{
// if any piece has been destroyed return false
// if any piece is not destroyed then return true
trigger notify("no valid boards");
return;
}

}
}
}

random_destroyed_chunk_show( )
{
wait( 0.5 );
self Show();
}


// jl this calls a rumble and zombie scream on the players if they are next to a door being opened.
// call a distance check of the the last chunk replaced
door_repaired_rumble_n_sound()
{
players = GetPlayers();
//players[0] PlayRumbleOnEntity("damage_heavy");
// only do this if they are close enough
// add distnace check

for(i = 0; i {

if (distance (players[i].origin, self.origin) {

if(isalive(players[i]))
//-- not usedif(isalive(players[i]) && (isdefined(players[i].pers["team"])) && (players[i].pers["team"] == team))
{

players[i] thread board_completion();

}
}
}
}

board_completion()
{
self endon ("disconnect");

// need to be place a delay if done within a certain time frame
//wait(1.2);
//self play_sound_on_ent( "purchase" );
//players[i] iprintlnbold("Entrance 1 is fixed!!!");
//wait(0.3);
//self play_sound_on_ent( "purchase" );
//wait(0.3);
//self play_sound_on_ent( "purchase" );
}


// self is a trigger that is spawned off of the exterior_goal entity.
trigger_delete_on_repair()
{
while( IsDefined( self ) )
{
self waittill_either("all_boards_repaired", "no valid boards");
self thread door_repaired_rumble_n_sound(); // jl added cool repair sound
self delete(); // when the boards are totally repaired then delete your self
break;
}

}

blocker_doubler_hint( hint, original_cost )
{
self endon( "death" );

doubler_status = level.zombie_vars["zombie_powerup_point_doubler_on"];
while( 1 )
{
wait( 0.5 );

if( doubler_status != level.zombie_vars["zombie_powerup_point_doubler_on"] )
{
doubler_status = level.zombie_vars["zombie_powerup_point_doubler_on"];
cost = original_cost;
if( level.zombie_vars["zombie_powerup_point_doubler_on"] )
{
cost = original_cost * 2;
}

self set_hint_string( self, hint + cost );
}
}
}

rebuild_barrier_reward_reset()
{
self.rebuild_barrier_reward = 0;
}

remove_chunk( chunk, node, destroy_immediately, zomb )
{
chunk update_states("mid_tear");

// jl dec 15 09
// jl added check for differnt types of windows
if(IsDefined(chunk.script_parameters))
{
if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board") // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{
chunk thread zombie_boardtear_audio_offset(chunk);
}
}

if(IsDefined(chunk.script_parameters))
{
if( chunk.script_parameters == "bar" ) // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{
chunk thread zombie_bartear_audio_offset(chunk);
}
}


chunk NotSolid();
// here I do a check for if it is a bar

//if ( isdefined( destroy_immediately ) && destroy_immediately)
//{
// chunk.destroyed = true;
//}

fx = "wood_chunk_destory";
if( IsDefined( self.script_fxid ) )
{
fx = self.script_fxid;
}



if ( IsDefined( chunk.script_moveoverride ) && chunk.script_moveoverride )
{
chunk Hide();
}


// an origin is created and the current chunk is linked to it. Then it flings the chunk and deletes the origin
if ( IsDefined( chunk.script_parameters ) && ( chunk.script_parameters == "bar" ) )
{

// added top bar check so it goes less higher
if( IsDefined ( chunk.script_noteworthy ) && ( chunk.script_noteworthy == "4" ) )
{
ent = Spawn( "script_origin", chunk.origin );
ent.angles = node.angles +( 0, 180, 0 );
dist = 100 + RandomInt( 100 );
dest = ent.origin + ( AnglesToForward( ent.angles ) * dist );
trace = BulletTrace( dest + ( 0, 0, 16 ), dest + ( 0, 0, -200 ), false, undefined );

if( trace["fraction"] == 1 )
{
dest = dest + ( 0, 0, -200 );
}
else
{
dest = trace["position"];
}

// time = 1;
chunk LinkTo( ent );

//time = ent fake_physicslaunch( dest, 200 + RandomInt( 100 ) );
time = ent fake_physicslaunch( dest, 300 + RandomInt( 100 ) );


if( RandomInt( 100 ) > 40 )
{
ent RotatePitch( 180, time * 0.5 );
}
else
{
ent RotatePitch( 90, time, time * 0.5 );
}
wait( time );

chunk Hide();

// try sending the notify now...
wait( 0.1);
//wait( 1 ); // the notify is sent out late... so I can't call it right away...
// I need to keep track of what the last peice is...
ent Delete();
}

else
{
ent = Spawn( "script_origin", chunk.origin );
ent.angles = node.angles +( 0, 180, 0 );
dist = 100 + RandomInt( 100 );
dest = ent.origin + ( AnglesToForward( ent.angles ) * dist );
trace = BulletTrace( dest + ( 0, 0, 16 ), dest + ( 0, 0, -200 ), false, undefined );

if( trace["fraction"] == 1 )
{
dest = dest + ( 0, 0, -200 );
}
else
{
dest = trace["position"];
}

// time = 1;
chunk LinkTo( ent );

time = ent fake_physicslaunch( dest, 260 + RandomInt( 100 ) );

// here you will do a random damage... however it would be better if you made them fall over
// call damage function out of here so the wait doesn't interrupt normal flow.
thread random_damage_zombie_behind_bar( chunk, zomb );



//time = ent fake_physicslaunch( dest, 200 + RandomInt( 100 ) );

//forward = AnglesToForward( ent.angles + ( -60, 0, 0 ) ) * power );
//ent MoveGravity( forward, time );

if( RandomInt( 100 ) > 40 )
{
ent RotatePitch( 180, time * 0.5 );
}
else
{
ent RotatePitch( 90, time, time * 0.5 );
}
wait( time );

chunk Hide();

// try sending the notify now...
wait( 0.1);
//wait( 1 ); // the notify is sent out late... so I can't call it right away...
// I need to keep track of what the last peice is...
ent Delete();

}
//if (isdefined( destroy_immediately ) && destroy_immediately)
//{
// return;
//}
chunk update_states("destroyed");
chunk notify( "destroyed" );
}

Link to comment

Part 2 of above


if ( IsDefined ( chunk.script_parameters ) && chunk.script_parameters == "board" || chunk.script_parameters == "repair_board" )
{

ent = Spawn( "script_origin", chunk.origin );
ent.angles = node.angles +( 0, 180, 0 );
dist = 100 + RandomInt( 100 );
dest = ent.origin + ( AnglesToForward( ent.angles ) * dist );
trace = BulletTrace( dest + ( 0, 0, 16 ), dest + ( 0, 0, -200 ), false, undefined );

if( trace["fraction"] == 1 )
{
dest = dest + ( 0, 0, -200 );
}
else
{
dest = trace["position"];
}

// time = 1;
chunk LinkTo( ent );

time = ent fake_physicslaunch( dest, 200 + RandomInt( 100 ) );
//time = ent fake_physicslaunch( dest, 200 + RandomInt( 100 ) );

// forward = AnglesToForward( ent.angles + ( -60, 0, 0 ) ) * power );
// ent MoveGravity( forward, time );

// DCS 090110: delete glass or wall piece before sending flying.
//DCS 090910: but not metal.
if(IsDefined(chunk.unbroken_section))
{
if(!IsDefined(chunk.material) || chunk.material != "metal")
{
chunk.unbroken_section self_delete();
}
}

if( RandomInt( 100 ) > 40 )
{
ent RotatePitch( 180, time * 0.5 );
}
else
{
ent RotatePitch( 90, time, time * 0.5 );
}
wait( time );

// DCS 090910: let the metal vents go fly.
if(IsDefined(chunk.unbroken_section))
{
if(IsDefined(chunk.material) && chunk.material == "metal")
{
chunk.unbroken_section self_delete();
}
}

chunk Hide();

// try sending the notify now...
wait( 0.1);
//wait( 1 ); // the notify is sent out late... so I can't call it right away...
// I need to keep track of what the last peice is...
ent Delete();


//if (isdefined( destroy_immediately ) && destroy_immediately)
//{
// return;
//}

chunk update_states("destroyed");
chunk notify( "destroyed" );
}


if ( IsDefined ( chunk.script_parameters ) && ( chunk.script_parameters == "grate" ) )
{
// Only make the last piece of the grate get pulled off.
if( IsDefined ( chunk.script_noteworthy ) && ( chunk.script_noteworthy == "6" ) )
{
// angles = node.angles +( 0, 180, 0 );
// force = AnglesToForward( angles + ( -60, 0, 0 ) ) * ( 200 + RandomInt( 100 ) );
// chunk PhysicsLaunch( chunk.origin, force );

ent = Spawn( "script_origin", chunk.origin );
ent.angles = node.angles +( 0, 180, 0 );
dist = 100 + RandomInt( 100 );
dest = ent.origin + ( AnglesToForward( ent.angles ) * dist );
trace = BulletTrace( dest + ( 0, 0, 16 ), dest + ( 0, 0, -200 ), false, undefined );

if( trace["fraction"] == 1 )
{
dest = dest + ( 0, 0, -200 );
}
else
{
dest = trace["position"];
}

// time = 1;
chunk LinkTo( ent );

time = ent fake_physicslaunch( dest, 200 + RandomInt( 100 ) );
//time = ent fake_physicslaunch( dest, 200 + RandomInt( 100 ) );

// forward = AnglesToForward( ent.angles + ( -60, 0, 0 ) ) * power );
// ent MoveGravity( forward, time );

if( RandomInt( 100 ) > 40 )
{
ent RotatePitch( 180, time * 0.5 );
}
else
{
ent RotatePitch( 90, time, time * 0.5 );
}
wait( time );
chunk Hide();
//wait( 1 ); // the notify is sent out late... so I can't call it right away...
// I need to keep track of what the last peice is...
ent Delete();
chunk update_states("destroyed");
chunk notify( "destroyed" );
}

else
{
chunk Hide();
//chunk moveto( chunk.origin + ( 0, 0, -1000 ), 0.3, 0.1, 0.1 );
chunk update_states("destroyed");
chunk notify( "destroyed" );
}
//chunk Hide();
}

/*
// this is kicking off but is to late to send the notify
if( all_chunks_destroyed( node.barrier_chunks ) )
{

if( IsDefined( node.clip ) )
{
node.clip ConnectPaths();
wait( 0.05 );
node.clip disable_trigger();
}
else
{
for( i = 0; i {
node.barrier_chunks[i] ConnectPaths();
}
}
}
else
{
EarthQuake( RandomFloatRange( 1, 3 ), 0.9, chunk.origin, 500 );
}
*/
}


random_damage_zombie_behind_bar( chunk, zomb )
{
zomb endon( "death" );
// I would like to play random knockdown ani
if ( IsDefined (chunk.script_parameters) && chunk.script_parameters == "bar" )
{
//random_chance = RandomInt( 11 );
//if( random_chance >= 4 )
//{

// I need this to be self

//wait ( RandomFloat( 0.5 ) + 0.5 )
//self = zombs
zombs = GetAIArray ( "axis" );

//for( i = 0; i for( i = 0; i {
if(Distance ( chunk.origin, zombs[i].origin ) {
if( 10 > RandomIntRange( 1, 100 ) )
{
// Degug test IPrintLnBold ( "DAMAGE DONE TO ZOMBIE FROM BAR YEAH" );
if ( IsAlive( zombs[i] ) )
{
wait( 0.3 );
// now I need to make it happen less often
//zombs[i].random_bar_knock_down = true;
RadiusDamage( chunk.origin, 100, 10, 5 );
}

wait( 1 );
if ( IsAlive( zombs[i] ) )
{
//zombs[i].random_bar_knock_down = false;
}
}
}
}
//}
}
}

// jl dec 15 09
remove_chunk_rotate_grate( chunk )
{
// this is going to rotate all of them.. I need to some how do this off of the node pointing to it..
//chunk_rotate_piece = GetEntArray( "grate", "script_parameters");

//chunk_rotate_piece = GetEnt( "grate", "script_parameters");
//chunk vibrate(( 0, 270, 0 ), 0.2, 0.4, 0.4);


// how do I only effect the one for that window and not affect all of them
// This is actually checked every time

if( IsDefined (chunk.script_parameters) && chunk.script_parameters == "grate" ) //&& chunk.script_parameters != "grate" )
{
chunk vibrate(( 0, 270, 0 ), 0.2, 0.4, 0.4);
return;
}
}

// jl just for now I added an audio offset to give more length and depth to the tearing off feeling
// i should add these to the same area where the fx is called, which is zombie_boardtear_offset_fx_horizontle(chunk)
// in zombiemode_spawner
zombie_boardtear_audio_offset(chunk)
{
if( IsDefined(chunk.material) && !IsDefined( chunk.already_broken ) )
chunk.already_broken = false;

if( IsDefined(chunk.material) && chunk.material == "glass" && chunk.already_broken == false )
{
chunk PlaySound( "zmb_break_glass_barrier" );
wait( randomfloat( 0.3, 0.6 ));
chunk PlaySound( "zmb_break_glass_barrier" );
chunk.already_broken = true;
}
else if( IsDefined(chunk.material) && chunk.material == "metal" && chunk.already_broken == false )
{
chunk PlaySound( "grab_metal_bar" );
wait( randomfloat( 0.3, 0.6 ));
chunk PlaySound( "break_metal_bar" );
chunk.already_broken = true;
}
else
{
chunk play_sound_on_ent( "break_barrier_piece" );
wait( randomfloat( 0.3, 0.6 )); // 06 might be too much, a little seperation sounds great...
chunk play_sound_on_ent( "break_barrier_piece" );
chunk.already_broken = true;
}
}

zombie_bartear_audio_offset(chunk)
{
chunk play_sound_on_ent( "grab_metal_bar" );
//iprintlnbold("RRIIIPPPPP!!!");
wait( randomfloat( 0.3, 0.6 ));
chunk play_sound_on_ent( "break_metal_bar" );
wait( randomfloat( 1.0, 1.3 ));
chunk play_sound_on_ent( "drop_metal_bar" );
}

replace_chunk( chunk, perk, via_powerup )
{
chunk update_states("mid_repair");
assert( IsDefined( chunk.og_origin ) );
assert( IsDefined( chunk.og_angles ) );

has_perk = false;

if( isDefined( perk ) )
{
has_perk = true;
}

// need to remove this for the bar bend repair
//chunk Show();

sound = "rebuild_barrier_hover";
if( IsDefined( chunk.script_presound ) )
{
sound = chunk.script_presound;
}


if( !isdefined( via_powerup ) )
{
play_sound_at_pos( sound, chunk.origin );
}


only_z = ( chunk.origin[0], chunk.origin[1], chunk.og_origin[2] );

// JL I setup the bar check on the inside of the else, but I will probably need to make it the first check and incompass all of it.

if( IsDefined(chunk.script_parameters) )
{

if( chunk.script_parameters == "board" ) // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{
chunk Show();

if( has_perk )
{
if( "specialty_fastreload" == perk )
{

chunk RotateTo( chunk.og_angles, 0.15 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.1 );
}
else if( "specialty_fastreload_upgrade" == perk )
{

chunk RotateTo( chunk.og_angles, 0.08 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.1 );
}
}
else
{
chunk RotateTo( chunk.angles + ( 0, -9, 0 ) , 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ) , 0.1 );
chunk waittill ("rotatedone");
chunk MoveTo( only_z, 0.15);
chunk RotateTo( chunk.og_angles, 0.3 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.2 );
}
}
// DCS: new start in good shape.
else if(chunk.script_parameters == "repair_board" )
{
if(IsDefined(chunk.unbroken_section))
{
chunk.unbroken_section self_delete();
chunk Show();
}
else
{
chunk Show();
}

if( has_perk )
{
if( "specialty_fastreload" == perk )
{

chunk RotateTo( chunk.og_angles, 0.15 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.1 );
}
else if( "specialty_fastreload_upgrade" == perk )
{

chunk RotateTo( chunk.og_angles, 0.08 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.1 );
}
}
else
{
chunk RotateTo( chunk.angles + ( 0, -9, 0 ) , 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ) , 0.1 );
chunk waittill ("rotatedone");
chunk MoveTo( only_z, 0.15);
chunk RotateTo( chunk.og_angles, 0.3 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.2 );
}
}


if( IsDefined(chunk.script_parameters) )
{

if( chunk.script_parameters == "bar" ) // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{

chunk Show();

if( has_perk )
{
if( "specialty_fastreload" == perk )
{
chunk RotateTo( chunk.og_angles, 0.15 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.1 );
}
else if( "specialty_fastreload_upgrade" == perk )
{

chunk RotateTo( chunk.og_angles, 0.08 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.1 );
}
}



if(chunk.script_noteworthy == "3" || chunk.script_noteworthy == "5")
{
// bend model back here... send notify0.
}

// was 180
chunk RotateTo( chunk.angles + ( 0, -9, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk MoveTo( only_z, 0.15);
chunk RotateTo( chunk.og_angles, 0.3 );
chunk waittill_notify_or_timeout( "rotatedone", 1 );
wait( 0.2 );
}
}
}

//Jl seperate board and bar type checks now
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board") // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{

if( has_perk )
{
if( "specialty_fastreload" == perk )
{
chunk MoveTo( chunk.og_origin, 0.05 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
}
else if( "specialty_fastreload_upgrade" == perk )
{
chunk MoveTo( chunk.og_origin, 0.03 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
}
}
else
{
chunk RotateTo( chunk.angles + ( 0, -9, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.og_angles, 0.1 );
chunk waittill_notify_or_timeout( "RotateTo", 0.1 );
chunk MoveTo( chunk.og_origin, 0.1 );
chunk waittill_notify_or_timeout( "movedone", 1 ); // the time out is playing crashing out
assert( chunk.origin == chunk.og_origin );
// jl try flipping the boards as they move in to add more impact
}
}
}

if(isdefined(chunk.script_parameters))
{

if( chunk.script_parameters == "bar" ) // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{



if( has_perk )
{
if( "specialty_fastreload" == perk )
{
chunk Show();
chunk MoveTo( chunk.og_origin, 0.05 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
}
else if( "specialty_fastreload_upgrade" == perk )
{
chunk Show();
chunk MoveTo( chunk.og_origin, 0.03 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
}
}
else if(chunk.script_noteworthy == "3") // bend repiar
{
chunk RotateTo( chunk.angles + ( 0, -9, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.og_angles, 0.1 );
chunk MoveTo( chunk.og_origin, 0.1 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
//targets[j].destroyed = false;
//level notify ("reset_bar_left");
chunk Show();
}

else if(chunk.script_noteworthy == "5") // bend repiar
{
chunk RotateTo( chunk.angles + ( 0, -9, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.og_angles, 0.1 );
chunk MoveTo( chunk.og_origin, 0.1 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
// change this to chunk set
//level notify ("reset_bar_right");
chunk Show();
}

else
{
chunk Show();
// jl added extra rotation for extra flair
// 20, 25 these felt good
chunk RotateTo( chunk.angles + ( 0, -9, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.angles + ( 0, 18, 0 ), 0.1 );
chunk waittill ("rotatedone");
chunk RotateTo( chunk.og_angles, 0.1 );
chunk MoveTo( chunk.og_origin, 0.1 );
chunk waittill_notify_or_timeout( "movedone", 1 );
assert( chunk.origin == chunk.og_origin );
// jl try flipping the boards as they move in to add more impact
}
}
}

if( IsDefined(chunk.script_parameters) )
{

if( chunk.script_parameters == "grate" ) // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{
// Replace the grate
if( IsDefined ( chunk.script_noteworthy ) && ( chunk.script_noteworthy == "6" ) )
{
amplitude1 = RandomfloatRange( 10, 15); // the amount of vibration in a degree , this feels good for wood but too much for bars
period1 = RandomfloatRange( 0.3, 0.5); // number of vibrations within one second
time1 = RandomfloatRange( 0.3, 0.4); // total time to move
chunk vibrate(( 0, 180, 0 ), amplitude1, period1, time1); // this looks really cool.. very sppplke
wait(0.3);
chunk RotateTo( chunk.og_angles, 0.1 );
chunk MoveTo( chunk.og_origin, 0.1 );
chunk waittill_notify_or_timeout( "movedone", 1 );
// jl 02/11/10 I removed the line below because we don't need this check
Assert( chunk.origin == chunk.og_origin );
// change this to chunk set
//level notify ("reset_bar_right");
chunk thread zombie_gratetear_audio_plus_fx_offset_repair_horizontal( chunk );
chunk Show();
}

// If they are not noteworthy six then do a check for the entity index
else
{

// was 180 chunk vibrate(( 0, 270, 0 ), 5, 1, 0.3);
//wait(0.3);
//chunk moveto( chunk.origin + ( 0, 0, 1000 ), 0.3, 0.1, 0.1 );
wait( 0.5 );
chunk waittill_notify_or_timeout( "movedone", 1 );
chunk thread zombie_gratetear_audio_plus_fx_offset_repair_horizontal( chunk );
chunk Show();
}
}
}


// jl moved this to another location
//chunk waittill_notify_or_timeout( "movedone", 1 );
//assert( chunk.origin == chunk.og_origin );

// Jl commented out
sound = "barrier_rebuild_slam";
if( IsDefined( self.script_ender ) )
{
sound = self.script_ender;
}

//TUEY Play the sounds
// JL, hey Tuey I added calls in here for our different windows so we can call different sounds
if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "board" || chunk.script_parameters == "repair_board") // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{
if(chunk.script_noteworthy == "1" || chunk.script_noteworthy == "5" || chunk.script_noteworthy == "6")
{
chunk thread zombie_boardtear_audio_plus_fx_offset_repair_horizontal(chunk);
}
else
{
chunk thread zombie_boardtear_audio_plus_fx_offset_repair_verticle(chunk);
}

}
}

if(isdefined(chunk.script_parameters))
{
if( chunk.script_parameters == "bar" ) // jl this is new check to see if it is a board then do board anims, this needs to hold the entire function
{
if(chunk.script_noteworthy == "4" || chunk.script_noteworthy == "6")
{
// Jluyties 03/09/10 I commented out fx for non model bars till we get the models
if( IsDefined( chunk.script_squadname ) && ( chunk.script_squadname == "cosmodrome_storage_area" ) )
{
// I need to kill this thread.
}

if (!IsDefined( chunk.script_squadname ) )
{
// this doesn't work because it calls it at the beggining, I need to find where it locks into place
chunk thread zombie_bartear_audio_plus_fx_offset_repair_horizontal(chunk);
}
}
else
{
// Jluyties 03/09/10 I commented out fx for non model bars till we get the models
if ( IsDefined( chunk.script_squadname ) && ( chunk.script_squadname == "cosmodrome_storage_area" ) )
{
// I need to kill this thread.
}
if (!IsDefined( chunk.script_squadname ) )
{
// this doesn't work because it calls it at the beggining, I need to find where it locks into place
chunk thread zombie_bartear_audio_plus_fx_offset_repair_verticle(chunk);
}
}

}
}

chunk Solid();
chunk update_states("repaired");

fx = "wood_chunk_destory";
if( IsDefined( self.script_fxid ) )
{
fx = self.script_fxid;
}

if( !IsDefined( via_powerup ) )
{
play_sound_at_pos( sound, chunk.origin );
//wait( randomfloat( 0.3, 0.6 ));
//play_sound_at_pos( sound, chunk.origin );
//playfx( level._effect[fx], chunk.origin ); // need to call at offset
//JL u need to call the offset for particles and sounds from here
//playfx( level._effect[fx], chunk.origin +( randomint( 20 ), randomint( 20 ), randomint( 10 ) ) );
//playfx( level._effect[fx], chunk.origin +( randomint( 40 ), randomint( 40 ), randomint( 20 ) ) );
}

if( !Isdefined( self.clip ) )
{
chunk Disconnectpaths();
}

}

// Jl we want different audio for each type of board or bar when they are repaired
// Need tags so the off sets for the effects is less code.
zombie_boardtear_audio_plus_fx_offset_repair_horizontal( chunk )
{
EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 ); // do I want an increment if more are gone...

//chunk play_sound_on_ent( "break_barrier_piece" );
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (0, 0, 30));
wait( randomfloat( 0.3, 0.6 )); // 06 might be too much, a little seperation sounds great...
chunk play_sound_on_ent( "break_barrier_piece" );
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (0, 0, -30));
// I need to add repair fx
}

zombie_boardtear_audio_plus_fx_offset_repair_verticle( chunk )
{
EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 ); // do I want an increment if more are gone...
//chunk play_sound_on_ent( "break_barrier_piece" );
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (30, 0, 0));
wait( randomfloat( 0.3, 0.6 )); // 06 might be too much, a little seperation sounds great...
chunk play_sound_on_ent( "break_barrier_piece" );
PlayFx( level._effect["wood_chunk_destory"], chunk.origin + (-30, 0, 0));
// I need to add repair fx
}


zombie_gratetear_audio_plus_fx_offset_repair_horizontal( chunk )
{
EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 ); // do I want an increment if more are gone...
chunk play_sound_on_ent( "bar_rebuild_slam" );

switch( randomInt( 9 ) ) // This sets up random versions of the bars being pulled apart for variety
{
case 0:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;

case 1:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );

break;

case 2:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );

break;

case 3:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );

break;

case 4:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
wait( randomfloat( 0.0, 0.3 ));
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;

case 5:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 6:
PlayFX( level._effect["fx_zombie_bar_break_lite"], chunk.origin + (-30, 0, 0) );
break;
case 7:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
break;
case 8:
PlayFX( level._effect["fx_zombie_bar_break"], chunk.origin + (-30, 0, 0) );
break;
}

}


zombie_bartear_audio_plus_fx_offset_repair_horizontal( chunk )
{
EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 ); // do I want an increment if more are gone...
chunk play_sound_on_ent( "bar_rebuild_slam" );


switch( randomInt( 9 ) ) // This sets up random versions of the bars being pulled apart for variety
{
case 0:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;

case 1:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;

case 2:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;

case 3:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;

case 4:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;

case 5:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_left" );
break;
case 6:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_right" );
break;
case 7:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_left" );
break;
case 8:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_right" );
break;
}

}

zombie_bartear_audio_plus_fx_offset_repair_verticle(chunk)
{
EarthQuake( RandomFloatRange( 0.3, 0.4 ), RandomFloatRange(0.2, 0.4), chunk.origin, 150 ); // do I want an increment if more are gone...
chunk play_sound_on_ent( "bar_rebuild_slam" );


switch( randomInt( 9 ) ) // This sets up random versions of the bars being pulled apart for variety
{
case 0:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;

case 1:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
break;

case 2:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
break;

case 3:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;

case 4:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
wait( randomfloat( 0.0, 0.3 ));
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;

case 5:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_top" );
break;
case 6:
PlayFXOnTag( level._effect["fx_zombie_bar_break_lite"], chunk, "Tag_fx_bottom" );
break;
case 7:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_top" );
break;
case 8:
PlayFXOnTag( level._effect["fx_zombie_bar_break"], chunk, "Tag_fx_bottom" );
break;
}
}

add_new_zombie_spawners()
{
if( isdefined( self.target ) )
{
self.possible_spawners = getentarray( self.target, "targetname" );
}

if( isdefined( self.script_string ) )
{
spawners = getentarray( self.script_string, "targetname" );
self.possible_spawners = array_combine( self.possible_spawners, spawners );
}

if( !isdefined( self.possible_spawners ) )
{
return;
}

// add new check if they've been added already
zombies_to_add = self.possible_spawners;

for( i = 0; i {
self.possible_spawners[i].is_enabled = true;
add_spawner( self.possible_spawners[i] );
}
}

//
// Flag Blocker ----------------------------------------------------------------------------------- //
//

flag_blocker()
{
if( !IsDefined( self.script_flag_wait ) )
{
AssertMsg( "Flag Blocker at " + self.origin + " does not have a script_flag_wait key value pair" );
return;
}

if( !IsDefined( level.flag[self.script_flag_wait] ) )
{
flag_init( self.script_flag_wait );
}

type = "connectpaths";
if( IsDefined( self.script_noteworthy ) )
{
type = self.script_noteworthy;
}

flag_wait( self.script_flag_wait );

self script_delay();

if( type == "connectpaths" )
{
self ConnectPaths();
//FOCKER
//iprintlnbold("BOARDS AREE ALL DOWN!!!");
self disable_trigger();
return;
}

if( type == "disconnectpaths" )
{
self DisconnectPaths();
//iprintlnbold("BOARDS ARE ALL UP!!!");
self disable_trigger();
return;
}

AssertMsg( "flag blocker at " + self.origin + ", the type \"" + type + "\" is not recognized" );
}

update_states( states )
{
assertex( isdefined( states ) );

self.state = states;

}


//*****************************************************************************
// SHUTTERS - they cover windows and prevent zombies from spawning and entering through them
//
// Shutter Switch Trigger
// targetname "window_shutter"
// target targets all related entities. script will sort them out
// script_int number of players needed to keep shutter open
// If you have fewer players, the shutter will be closed permanently
// script_wait length of time to keep shutter closed once activated
//
// Shutter Switch Trigger targets the following:
//
// Area affected by the shutter
// trigger_multi - (all things that must be killed or deactivated must be encompased by this)/
//
// Shutter Switch Model
// script_model
//
// Shutter Light
// script_model - changes color depending on usage
//
// Shutter
// script_model/brushmodel - the thing that will move to cover the window
// script_string the movement mode the shutter will use, like "move"
// (see doors, may require other fields to be set)
//
//*****************************************************************************
shutter_init()
{
// Find shutter, handle, light & trigger
self.shutters = [];
self.lights = [];
self.area_triggers = [];
// self.type = undefined;

targets = GetEntArray(self.target, "targetname" );
for(i=0;i {
if ( IsDefined( targets[i].script_string ) )
{
self.shutters[ self.shutters.size ] = targets[i];
}
else if(targets[i].classname == "trigger_multiple")
{
self.area_triggers[ self.area_triggers.size ] = targets[i];
}
else if(targets[i].classname == "script_model")
{
if (targets[i].model == "zombie_zapper_cagelight" )
{
self.lights[ self.lights.size ] = targets[i];
}
else if(targets[i].model == "zombie_zapper_handle")
{
self.handle = targets[i];
}
}
}

// Add check for number of players
flag_wait( "all_players_connected" );
players = GetPlayers();

// If the number of players is >= self.script_int keep it open
min_size = 4;
if ( IsDefined( self.script_int ) )
{
min_size = self.script_int;
}

if ( players.size > min_size )
{
//make light green. may start red if we decide to connect to power
shutter_light_green( self.lights );

// Door has been activated, make it do its thing
for(i=0;i {
if( self.shutters[i].script_string == "anim" )
{
AssertEx( IsDefined( self.shutters[i].script_animname ), "Blocker_init: You must specify a script_animname for "+self.shutters[i].targetname );
AssertEx( IsDefined( level.scr_anim[ self.shutters[i].script_animname ] ), "Blocker_init: You must define a level.scr_anim for script_anim -> "+self.shutters[i].script_animname );
AssertEx( IsDefined( level.blocker_anim_func ), "Blocker_init: You must define a level.blocker_anim_func" );
}
self.shutters[i] door_activate( 0.05 );
}

cost = 1000;
if( IsDefined( self.zombie_cost ) )
{
cost = self.zombie_cost;
}

self set_hint_string( self, "default_buy_door_" + cost );
// self thread add_teampot_icon();
// self UseTriggerRequireLookAt();
self thread shutter_think();
}
else // shut it down permanently
{
//make light red
// shutter_light_red( self.lights );

// Keep it off
self disable_trigger();

self thread shutter_enable_zone( false );
}
}

//*****************************************************************************
// Swaps a cage light model to the red one.
//*****************************************************************************
shutter_light_red( shutter_lights )
{
for(i=0;i {
shutter_lights[i] setmodel("zombie_zapper_cagelight_red");

if(isDefined(shutter_lights[i].fx))
{
shutter_lights[i].fx delete();
}

shutter_lights[i].fx = maps\_zombiemode_net::network_safe_spawn( "trap_light_red", 2, "script_model", shutter_lights[i].origin );
shutter_lights[i].fx setmodel("tag_origin");
shutter_lights[i].fx.angles = shutter_lights[i].angles+(-90,0,0);
playfxontag(level._effect["zapper_light_notready"],shutter_lights[i].fx,"tag_origin");
}
}


//*****************************************************************************
// Swaps a cage light model to the green one.
//*****************************************************************************
shutter_light_green( shutter_lights )
{
for(i=0;i {
shutter_lights[i] setmodel("zombie_zapper_cagelight_green");

if(isDefined(shutter_lights[i].fx))
{
shutter_lights[i].fx delete();
}

shutter_lights[i].fx = maps\_zombiemode_net::network_safe_spawn( "trap_light_green", 2, "script_model", shutter_lights[i].origin );
shutter_lights[i].fx setmodel("tag_origin");
shutter_lights[i].fx.angles = shutter_lights[i].angles+(-90,0,0);
playfxontag(level._effect["zapper_light_ready"],shutter_lights[i].fx,"tag_origin");
}
}


//*****************************************************************************
// It's a throw switch
//*****************************************************************************
shutter_move_switch()
{
if(IsDefined(self.handle))
{
// Rotate switch model
self.handle rotatepitch( 180, .5 );
self.handle playsound( "amb_sparks_l_b" );
self.handle waittill( "rotatedone" );

// When "available" notify hit, bring back the level
self notify( "switch_activated" );
self waittill( "available" );

self.handle rotatepitch( -180, .5 );
}
}


//*****************************************************************************
// Shutter think
// Wait until the handle's pulled and then close the shutter for X time
// Then reopen.
//*****************************************************************************
shutter_think()
{
while( 1 )
{
self waittill( "trigger", who );
if( !who UseButtonPressed() )
{
continue;
}

if( who in_revive_trigger() )
{
continue;
}

if( is_player_valid( who ) )
{
// Check to see if you can afford this and deduct money if so
players = get_players();
if ( players.size == 1 && who.score >= self.zombie_cost )
{
// solo buy
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost );
}
else if( level.team_pool[ who.team_num ].score >= self.zombie_cost )
{
// team buy
who maps\_zombiemode_score::minus_to_team_score( self.zombie_cost );
}
else if( level.team_pool[ who.team_num ].score + who.score >= self.zombie_cost )
{
// team funds + player funds
team_points = level.team_pool[ who.team_num ].score;
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost - team_points );
who maps\_zombiemode_score::minus_to_team_score( team_points );
}
else // Not enough money
{
play_sound_at_pos( "zmb_no_cha_ching", self.shutters[0].origin );
who maps\_zombiemode_audio::create_and_play_dialog( "general", "door_deny", undefined, 0 );
continue;
}

bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type door", who.playername, who.score, level.team_pool[ who.team_num ].score, level.round_number, self.zombie_cost, self.target, self.origin );
}

// shutter has been activated, make it do its thing

// rotate switch
self disable_trigger();
self thread shutter_move_switch();
shutter_light_red( self.lights );

// wait for switch to rotate
self waittill( "switch_activated" );

// Door has been activated, make it do its thing
for(i=0;i {
// Don't thread this so the doors don't move at once
self.shutters[i] door_activate( undefined, false );
}

self thread shutter_enable_zone( false );
delay = 10;
if ( IsDefined( self.script_wait ) )
{
delay = self.script_wait ;
}
wait( delay );

self notify( "available" );
self thread shutter_enable_zone( true );

// Deactivate the doors
for(i=0;i {
// Don't thread this so the doors don't move at once
self.shutters[i] door_activate( undefined, true );
}

// Let the switch get back up
wait(1);

shutter_light_green( self.lights );
self enable_trigger();
}
}


//
// Disables spawners and rise locations in the affected areas as
// well as killing any active spawners and adding them back into the spawn pool
// enable is true if enabling the area and false if disabling.
shutter_enable_zone( set_enable )
{
// Shut off the spawners
zkeys = GetArrayKeys( level.zones );
for( z=0; z {
zone_name = zkeys[z];
zone = level.zones[ zone_name ];
for(s=0;s {
for ( at=0; at {
if ( zone.spawners[s] IsTouching( self.area_triggers[at] ) )
{
zone.spawners[s].is_enabled = set_enable;
}
}
}

// Making an assumption that if one of the zone's spawners is in the array, then all of them are in the array
// for(ds=0;ds // {
// for ( at=0; at // {
// if ( zone.dog_spawners[ds] IsTouching( self.area_triggers[at] ) )
// {
// zone.dog_spawners[ds].is_enabled = set_enable;
// }
// }
// }

// Check rise locations
for(rl=0; rl {
for ( at=0; at {
//TODO Begin crazy hack to see if a struct is in the volume. Do not keep this crap in!!!
org = Spawn( "script_origin", zone.rise_locations[rl].origin );
if ( org IsTouching( self.area_triggers[at] ) )
{
zone.rise_locations[rl].is_enabled = set_enable;
}
org delete();
// if ( zone.rise_locations[rl] IsTouching( self.area_triggers[at] ) )
// {
// zone.rise_locations[rl].is_enabled = set_enable;
// }
}
}
}

// If we're disabling the area, we'll need to kill any AI in the area since they
// can't go anywhere
if ( !set_enable )
{
// First wait for the zone manager loop to cycle once and remove the
// spawn locations in the area from the list of available spawn locations
wait( 1.5 );

// Okay, now kill whoever's in the area
ai_array = GetAIArray( "axis" );
num_to_add = 0;
for ( ai_num = 0; ai_num {
ai = ai_array[ ai_num ];
for ( i=0; i {
if ( IsAlive(ai) && ai IsTouching( self.area_triggers[i] ) )
{
ai DoDamage( ai.health, ai.origin );
num_to_add++;
}
}
}

level.zombie_total += num_to_add;
}
}

Link to comment

Zombiemode_Bowie

#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;

bowie_init()
{
PrecacheItem( "zombie_bowie_flourish" );

if( isDefined( level.bowie_cost ) )
{
cost = level.bowie_cost;
}
else
{
cost = 3000;
}

bowie_triggers = GetEntArray( "bowie_upgrade", "targetname" );
for( i = 0; i {
knife_model = GetEnt( bowie_triggers[i].target, "targetname" );
knife_model hide();
bowie_triggers[i] thread bowie_think(cost);
bowie_triggers[i] SetHintString( &"ZOMBIE_WEAPON_BOWIE_BUY", cost );
bowie_triggers[i] setCursorHint( "HINT_NOICON" );
bowie_triggers[i] UseTriggerRequireLookAt();
}
}

bowie_think(cost)
{

self.first_time_triggered = false;

for( ;; )
{
self waittill( "trigger", player );
// if not first time and they have the weapon give ammo

if( !is_player_valid( player ) )
{
player thread ignore_triggers( 0.5 );
continue;
}

if( player in_revive_trigger() )
{
wait( 0.1 );
continue;
}

if( player isThrowingGrenade() )
{
wait( 0.1 );
continue;
}

if( player is_drinking() )
{
wait( 0.1 );
continue;
}

if( player HasWeapon( "bowie_knife_zm" ) || player HasWeapon( "minigun_zm" ) )
{
wait(0.1);
continue;
}

//Z2 - UPDATED Missing script API call : isSwitchingWeapons()
// if( player isSwitchingWeapons() )
// {
// wait(0.1);
// continue;
// }

current_weapon = player GetCurrentWeapon();
if( current_weapon == "mine_bouncing_betty"
|| current_weapon == "claymore_zm"
|| current_weapon == "minigun_zm" )
{
wait(0.1);
continue;
}

if (player maps\_laststand::player_is_in_laststand() || is_true( player.intermission ) )
{
wait(0.1);
continue;
}

//Z2 HasPerk( "specialty_altmelee" ) is returning undefined
// player_has_bowie = player HasPerk( "specialty_altmelee" );
player_has_bowie = false;

if( !player_has_bowie )
{
// else make the weapon show and give it
if( player.score >= cost )
{
if( self.first_time_triggered == false )
{
model = getent( self.target, "targetname" );
// model show();
model thread bowie_show( player );
self.first_time_triggered = true;
}

player maps\_zombiemode_score::minus_to_player_score( cost );

bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type weapon",
player.playername, player.score, level.team_pool[ player.team_num ].score, level.round_number, cost, "bowie_knife", self.origin );

player maps\_zombiemode_weapons::check_collector_achievement( "bowie_knife_zm" );

player give_bowie();

if ( player maps\_laststand::player_is_in_laststand() || is_true( player.intermission ) )
{
// if they're in laststand at this point then they won't have gotten the bowie, so don't hide the trigger
continue;
}

self SetInvisibleToPlayer( player );
player._bowie_zm_equipped = 1;
}
else
{
play_sound_on_ent( "no_purchase" );
player maps\_zombiemode_audio::create_and_play_dialog( "general", "no_money", undefined, 1 );
}
}
}
}

give_bowie()
{
//self SetPerk( "specialty_altmelee" );

gun = self do_bowie_flourish_begin();
self maps\_zombiemode_audio::create_and_play_dialog( "weapon_pickup", "bowie" );

self waittill_any( "fake_death", "death", "player_downed", "weapon_change_complete" );

// restore player controls and movement
self do_bowie_flourish_end( gun );
}

do_bowie_flourish_begin()
{
self increment_is_drinking();

self AllowLean( false );
self AllowAds( false );
self AllowSprint( false );
self AllowCrouch( true );
self AllowProne( false );
self AllowMelee( false );

wait( 0.05 );

if ( self GetStance() == "prone" )
{
self SetStance( "crouch" );
}

gun = self GetCurrentWeapon();
weapon = "zombie_bowie_flourish";

self GiveWeapon( weapon );
self SwitchToWeapon( weapon );

return gun;
}

do_bowie_flourish_end( gun )
{
assert( gun != "zombie_perk_bottle_doubletap" );
assert( gun != "zombie_perk_bottle_revive" );
assert( gun != "zombie_perk_bottle_jugg" );
assert( gun != "zombie_perk_bottle_sleight" );
assert( gun != "syrette_sp" );

self AllowLean( true );
self AllowAds( true );
self AllowSprint( true );
self AllowProne( true );
self AllowMelee( true );
weapon = "zombie_bowie_flourish";

// TODO: race condition?
if ( self maps\_laststand::player_is_in_laststand() || is_true( self.intermission ) )
{
self TakeWeapon(weapon);
return;
}

self decrement_is_drinking();

if ( self HasWeapon( "knife_ballistic_zm" ) )
{
self notify( "zmb_lost_knife" );
self TakeWeapon( "knife_ballistic_zm" );
self GiveWeapon( "knife_ballistic_bowie_zm" );

if ( gun == "knife_ballistic_zm" )
{
gun = "knife_ballistic_bowie_zm";
}
}
else if ( self HasWeapon( "knife_ballistic_upgraded_zm" ) )
{
self notify( "zmb_lost_knife" );
self TakeWeapon( "knife_ballistic_upgraded_zm" );
self GiveWeapon( "knife_ballistic_bowie_upgraded_zm", 0, self maps\_zombiemode_weapons::get_pack_a_punch_weapon_options( "knife_ballistic_bowie_upgraded_zm" ) );

if ( gun == "knife_ballistic_upgraded_zm" )
{
gun = "knife_ballistic_bowie_upgraded_zm";
}
}

self TakeWeapon(weapon);

self GiveWeapon( "bowie_knife_zm" );

if( self HasWeapon("knife_zm") )
{
self TakeWeapon( "knife_zm" );
}

if( self is_drinking() )
{
return;
}
else if ( gun == "knife_zm" ) // if all they had was the knife, we need to switch them to the bowie
{
self SwitchToWeapon( "bowie_knife_zm" );
}
else if ( gun != "none" && gun != "claymore_zm" )
{
self SwitchToWeapon( gun );
}
else
{
// try to switch to first primary weapon
primaryWeapons = self GetWeaponsListPrimaries();
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
{
self SwitchToWeapon( primaryWeapons[0] );
}
}
}

bowie_show( player )
{
player_angles = VectorToAngles( player.origin - self.origin );

player_yaw = player_angles[1];
weapon_yaw = self.angles[1];

yaw_diff = AngleClamp180( player_yaw - weapon_yaw );

if( yaw_diff > 0 )
{
yaw = weapon_yaw - 90;
}
else
{
yaw = weapon_yaw + 90;
}

self.og_origin = self.origin;
self.origin = self.origin +( AnglesToForward( ( 0, yaw, 0 ) ) * 8 );

wait( 0.05 );
self Show();

play_sound_at_pos( "weapon_show", self.origin, self );

time = 1;
self MoveTo( self.og_origin, time );
}
Zombiemode_Claymores
#include common_scripts\utility; 
#include maps\_utility;
#include maps\_zombiemode_utility;


/*------------------------------------
CLAYMORE STUFFS -
a rough prototype for now, needs a bit more polish

------------------------------------*/
init()
{
trigs = getentarray("claymore_purchase","targetname");
for(i=0; i {
model = getent( trigs[i].target, "targetname" );
model hide();
}

array_thread(trigs,::buy_claymores);
level thread give_claymores_after_rounds();

level.pickup_claymores = ::pickup_claymores;
level.pickup_claymores_trigger_listener = ::pickup_claymores_trigger_listener;

level.claymore_detectionDot = cos( 70 );
level.claymore_detectionMinDist = 20;
}

buy_claymores()
{
self.zombie_cost = 1000;
self sethintstring( &"ZOMBIE_CLAYMORE_PURCHASE" );
self setCursorHint( "HINT_NOICON" );

level thread set_claymore_visible();
self.claymores_triggered = false;

while(1)
{
self waittill("trigger",who);
if( who in_revive_trigger() )
{
continue;
}

if( who GetCurrentWeapon() == "minigun_zm" )
{
wait( 0.1 );
continue;
}

if( is_player_valid( who ) )
{

if( who.score >= self.zombie_cost )
{
if(!isDefined(who.has_claymores))
{
who.has_claymores = 1;
play_sound_at_pos( "purchase", self.origin );

//set the score
who maps\_zombiemode_score::minus_to_player_score( self.zombie_cost );
who maps\_zombiemode_weapons::check_collector_achievement( "claymore_zm" );
who thread claymore_setup();
who thread show_claymore_hint("claymore_purchased");

// JMA - display the claymores
if( self.claymores_triggered == false )
{
model = getent( self.target, "targetname" );
model thread maps\_zombiemode_weapons::weapon_show( who );
self.claymores_triggered = true;
}

trigs = getentarray("claymore_purchase","targetname");
for(i = 0; i {
trigs[i] SetInvisibleToPlayer(who);
}
}
else
{
who thread show_claymore_hint("already_purchased");
}
}
}
}
}

set_claymore_visible()
{
players = getplayers();
trigs = getentarray("claymore_purchase","targetname");

while(1)
{
for(j = 0; j {
if( !isdefined(players[j].has_claymores))
{
for(i = 0; i {
trigs[i] SetInvisibleToPlayer(players[j], false);
}
}
}

wait(1);
players = getplayers();
}
}

claymore_watch()
{
self endon("death");

while(1)
{
self waittill("grenade_fire",claymore,weapname);
if(weapname == "claymore_zm")
{
claymore.owner = self;
claymore thread satchel_damage();
claymore thread claymore_detonation();
claymore thread play_claymore_effects();

self notify( "zmb_enable_claymore_prompt" );
}
}
}

claymore_setup()
{
self thread claymore_watch();

self giveweapon("claymore_zm");
self setactionslot(4,"weapon","claymore_zm");
self setweaponammostock("claymore_zm",2);
}

pickup_claymores()
{
player = self.owner;

if ( !player hasweapon( "claymore_zm" ) )
{
player thread claymore_watch();

player giveweapon("claymore_zm");
player setactionslot(4,"weapon","claymore_zm");
player setweaponammoclip("claymore_zm",0);
player notify( "zmb_enable_claymore_prompt" );
}
else
{
clip_ammo = player GetWeaponAmmoClip( self.name );
clip_max_ammo = WeaponClipSize( self.name );
if ( clip_ammo >= clip_max_ammo )
{
player notify( "zmb_disable_claymore_prompt" ); // just to be safe
return;
}
}

self maps\_weaponobjects::pick_up();

clip_ammo = player GetWeaponAmmoClip( self.name );
clip_max_ammo = WeaponClipSize( self.name );
if ( clip_ammo >= clip_max_ammo )
{
player notify( "zmb_disable_claymore_prompt" );
}
}

pickup_claymores_trigger_listener( trigger, player )
{
self thread pickup_claymores_trigger_listener_enable( trigger, player );
self thread pickup_claymores_trigger_listener_disable( trigger, player );
}

pickup_claymores_trigger_listener_enable( trigger, player )
{
self endon( "delete" );

while ( true )
{
player waittill_any( "zmb_enable_claymore_prompt", "spawned_player" );

if ( !isDefined( trigger ) )
{
return;
}

trigger trigger_on();
trigger linkto( self );
}
}

pickup_claymores_trigger_listener_disable( trigger, player )
{
self endon( "delete" );

while ( true )
{
player waittill( "zmb_disable_claymore_prompt" );

if ( !isDefined( trigger ) )
{
return;
}

trigger unlink();
trigger trigger_off();
}
}

/*
waittill_not_moving()
{
prevorigin = self.origin;
while(1)
{
wait .1;
if ( self.origin == prevorigin )
break;
prevorigin = self.origin;
}
}
*/

shouldAffectWeaponObject( object )
{
pos = self.origin + (0,0,32);

dirToPos = pos - object.origin;
objectForward = anglesToForward( object.angles );

dist = vectorDot( dirToPos, objectForward );
if ( dist return false;

dirToPos = vectornormalize( dirToPos );

dot = vectorDot( dirToPos, objectForward );
return ( dot > level.claymore_detectionDot );
}

claymore_detonation()
{
self endon("death");

// wait until we settle
self waittill_not_moving();

detonateRadius = 96;

spawnFlag = 1;// SF_TOUCH_AI_AXIS
playerTeamToAllow = "axis";
if( isDefined( self.owner ) && isDefined( self.owner.pers["team"] ) && self.owner.pers["team"] == "axis" )
{
spawnFlag = 2;// SF_TOUCH_AI_ALLIES
playerTeamToAllow = "allies";
}

damagearea = spawn("trigger_radius", self.origin + (0,0,0-detonateRadius), spawnFlag, detonateRadius, detonateRadius*2);

damagearea enablelinkto();
damagearea linkto( self );

self thread delete_claymores_on_death( damagearea );

if(!isdefined(level.claymores))
level.claymores = [];
level.claymores = array_add( level.claymores, self );

if( level.claymores.size > 15 && GetDvar( #"player_sustainAmmo") != "0" )
level.claymores[0] delete();

while(1)
{
damagearea waittill( "trigger", ent );

if ( isdefined( self.owner ) && ent == self.owner )
continue;

if( isDefined( ent.pers ) && isDefined( ent.pers["team"] ) && ent.pers["team"] != playerTeamToAllow )
continue;

if ( !ent shouldAffectWeaponObject( self ) )
continue;

if ( ent damageConeTrace(self.origin, self) > 0 )
{
self playsound ("claymore_activated_SP");
wait 0.4;
if ( isdefined( self.owner ) )
self detonate( self.owner );
else
self detonate( undefined );

return;
}
}
}

delete_claymores_on_death(ent)
{
self waittill("death");
// stupid getarraykeys in array_remove reversing the order - nate
level.claymores = array_remove_nokeys( level.claymores, self );
wait .05;
if ( isdefined( ent ) )
ent delete();
}

satchel_damage()
{
// self endon( "death" );

self setcandamage(true);
self.health = 100000;

attacker = undefined;

playerTeamToAllow = "axis";
if( isDefined( self.owner ) && isDefined( self.owner.pers["team"] ) && self.owner.pers["team"] == "axis" )
{
playerTeamToAllow = "allies";
}

while(1)
{
self waittill("damage", amount, attacker);
self.health = self.maxhealth;
if ( !isplayer(attacker) )
continue;

if ( isdefined( self.owner ) && attacker == self.owner )
continue;

if( isDefined( attacker.pers ) && isDefined( attacker.pers["team"] ) && attacker.pers["team"] != playerTeamToAllow )
continue;

break;
}

if ( level.satchelexplodethisframe )
wait .1 + randomfloat(.4);
else
wait .05;

if (!isdefined(self))
return;

level.satchelexplodethisframe = true;

thread reset_satchel_explode_this_frame();

self detonate( attacker );
// won't get here; got death notify.
}

reset_satchel_explode_this_frame()
{
wait .05;
level.satchelexplodethisframe = false;
}

play_claymore_effects()
{
self endon("death");

self waittill_not_moving();

PlayFXOnTag( level._effect[ "claymore_laser" ], self, "tag_fx" );
}

give_claymores_after_rounds()
{
while(1)
{
level waittill( "between_round_over" );
{
players = get_players();
for(i=0;i {
if(isDefined(players[i].has_claymores))
{
players[i] giveweapon("claymore_zm");
players[i] setactionslot(4,"weapon","claymore_zm");
players[i] setweaponammoclip("claymore_zm",2);
}
}
}
}
}

init_hint_hudelem(x, y, alignX, alignY, fontscale, alpha)
{
self.x = x;
self.y = y;
self.alignX = alignX;
self.alignY = alignY;
self.fontScale = fontScale;
self.alpha = alpha;
self.sort = 20;
//self.font = "objective";
}

setup_client_hintelem()
{
self endon("death");
self endon("disconnect");

if(!isDefined(self.hintelem))
{
self.hintelem = newclienthudelem(self);
}
self.hintelem init_hint_hudelem(320, 220, "center", "bottom", 1.6, 1.0);
}


show_claymore_hint(string)
{
self endon("death");
self endon("disconnect");

if(string == "claymore_purchased")
text = &"ZOMBIE_CLAYMORE_HOWTO";
else
text = &"ZOMBIE_CLAYMORE_ALREADY_PURCHASED";

self setup_client_hintelem();
self.hintelem setText(text);
wait(3.5);
self.hintelem settext("");
}

Zombiemode_Deathcards
#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include animscripts\zombie_Utility;

//-----------------------------------------------------------------------------------
// setup the deathcards in the level
//-----------------------------------------------------------------------------------
init()
{
flag_wait( "all_players_connected" );

// create deathcard for each player
players = get_players();

if ( players.size > 0 )
{
for ( i = 0; i {
level.deathcards[i] = SpawnStruct();
}

//SetDvar( "player_lastStandBleedoutTime", "3" );

// setup func pointers
level.deathcard_laststand_func = ::deathcard_laststand;

if ( players.size > 1 )
{
level.deathcard_spawn_func = ::deathcard_spawn;
}
}
}

//-----------------------------------------------------------------------------------
// place deathcard in level when player dies
//-----------------------------------------------------------------------------------
deathcard_spawn()
{
dc = Spawn( "script_model", self.origin + ( 0, 0, 40 ) );
dc.angles = self.angles;
//deathcard SetModel( "tag_origin" );

//playfxontag(level._effect["powercell"],dc,"tag_origin");
dc SetModel( "zombie_revive" );

dc.player = self;

dc thread deathcard_timeout();
dc thread deathcard_wobble();
dc thread deathcard_grab();

// The player gets pro tip message to pick up their death card on the next round
self.pro_tip_death_card_round = level.round_number + 1;
}

//-----------------------------------------------------------------------------------
// save player weapon info, score, etc in the deathcard
//-----------------------------------------------------------------------------------
deathcard_laststand()
{
players = get_players();

// solo player gets everything back
if ( players.size == 1 )
{
dc = level.deathcards[0];
dc.player = self;
dc.weapon = [];
dc.score = self.score;

primaries = self GetWeaponsListPrimaries();
dc.weapon[0] = primaries[0];
dc.current_weapon = 0;
if ( primaries.size > 1 )
{
dc.weapon[1] = primaries[1];
currentWeapon = self GetCurrentWeapon();
if ( currentWeapon == dc.weapon[1] )
{
dc.current_weapon = 1;
}
}
//dc.abilities = self.abilities;
dc.curr_ability = self.curr_ability;

if ( maps\_zombiemode_weap_cymbal_monkey::cymbal_monkey_exists() )
{
dc.zombie_cymbal_monkey_count = self getweaponammoclip( "zombie_cymbal_monkey" );
}
}
else
{
for ( i = 0; i {
if ( players[i] == self )
{
dc = level.deathcards[i];
dc.player = self;

dc.weapon = [];
dc.current_weapon = -1;

// save 1/2 score
dc.score = int( self.score * 0.5 );

primaries = self GetWeaponsListPrimaries();

// default weapon is never put in a deathcard
if ( primaries[0] == "m1911_zm" )
{
dc.weapon[0] = "none";
}
else
{
// save weapons and 1/2 stock
dc.weapon[0] = primaries[0];
stock = self GetWeaponAmmoStock( primaries[0] );
dc.stockCount[0] = int( stock * 0.5 );
dc.current_weapon = 0;
}

if ( primaries.size > 1 )
{
// default weapon is never put in a deathcard
if ( primaries[1] == "m1911_zm" )
{
dc.weapon[1] = "none";
}
else
{
dc.weapon[1] = primaries[1];
stock = self GetWeaponAmmoStock( primaries[1] );
dc.stockCount[1] = int( stock * 0.5 );

currentWeapon = players[i] GetCurrentWeapon();
if ( currentWeapon == dc.weapon[1] )
{
dc.current_weapon = 1;
}
else
{
dc.current_weapon = 0;
}
}
}
else
{
dc.weapon[1] = "none";
}

// save perks
dc.perk = deathcard_save_perks( self );
//dc.abilities = self.abilities;
dc.curr_ability = self.curr_ability;

if ( maps\_zombiemode_weap_cymbal_monkey::cymbal_monkey_exists() )
{
dc.zombie_cymbal_monkey_count = self getweaponammoclip( "zombie_cymbal_monkey" );
}
}
}
}
}

//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
deathcard_save_perks( ent )
{
idx = 0;
perk_array = undefined;
if ( ent HasPerk( "specialty_armorvest" ) )
{
perk_array[idx] = "specialty_armorvest";
idx++;
}
else if ( ent HasPerk( "specialty_armorvest_upgrade" ) )
{
perk_array[idx] = "specialty_armorvest_upgrade";
idx++;
}
if ( ent HasPerk( "specialty_quickrevive" ) )
{
perk_array[idx] = "specialty_quickrevive";
idx++;
}
else if ( ent HasPerk( "specialty_quickrevive_upgrade" ) )
{
perk_array[idx] = "specialty_quickrevive_upgrade";
idx++;
}
if ( ent HasPerk( "specialty_fastreload" ) )
{
perk_array[idx] = "specialty_fastreload";
idx++;
}
else if ( ent HasPerk( "specialty_fastreload_upgrade" ) )
{
perk_array[idx] = "specialty_fastreload_upgrade";
idx++;
}
//if ( ent HasPerk( "specialty_rof" ) )
//{
// perk_array[idx] = "specialty_rof";
// idx++;
//}
return( perk_array );
}

//-----------------------------------------------------------------------------------
// wait for player to get deathcard
//-----------------------------------------------------------------------------------
deathcard_grab()
{
self endon( "deatchcard_timedout" );

wait( 1 );

while ( isdefined( self ) )
{
players = get_players();

for ( i = 0; i {
if ( players[i].is_zombie )
{
continue;
}

if ( players[i] == self.player )
{
dist = distance( players[i].origin, self.origin );
if ( dist {
playfx( level._effect["powerup_grabbed"], self.origin );
playfx( level._effect["powerup_grabbed_wave"], self.origin );

players[i] deathcard_give( i );

wait( 0.1 );

playsoundatposition("zmb_powerup_grabbed_3p", self.origin);
self stoploopsound();

self delete();
self notify( "deathcard_grabbed" );
players[i] clientnotify( "dc0" ); // play death card sound
}
}
}

wait_network_frame();
}
}

//-----------------------------------------------------------------------------------
// give back weapons, perks, money, etc...
//-----------------------------------------------------------------------------------
deathcard_give( index )
{
dc = level.deathcards[index];

if ( dc.current_weapon >= 0 )
{
weapon = undefined;
stock = 0;
needSwitch = false;

// try to give back the weapon player was holding
if ( dc.weapon[dc.current_weapon] != "none" && !self HasWeapon( dc.weapon[dc.current_weapon] ) )
{
weapon = dc.weapon[dc.current_weapon];
stock = dc.stockCount[dc.current_weapon];
needSwitch = true;
}
else
{
for ( i = 0; i {
if ( dc.current_weapon == i || dc.weapon[i] == "none" )
{
continue;
}

if ( !self HasWeapon( dc.weapon[i] ) )
{
weapon = dc.weapon[i];
stock = dc.stockCount[i];
}
}
}

// actually have something to give
if ( IsDefined( weapon ) )
{
primaries = self GetWeaponsListPrimaries();
if ( primaries.size >= 2 )
{
takeWeapon = undefined;

// always take default if the player has it and another
if ( primaries[0] == "m1911_zm" || primaries[1] == "m1911_zm" )
{
takeWeapon = "m1911_zm";
}
else
{
takeWeapon = self GetCurrentWeapon();
}

self TakeWeapon( takeWeapon );
}

self GiveWeapon( weapon, 0 );

self SetWeaponAmmoClip( weapon, WeaponClipSize( weapon ) );
self SetWeaponAmmoStock( weapon, stock );

if ( needSwitch )
{
self SwitchToWeapon( weapon, 0 );
}
}
}
// don't give points back
// score
//self.old_score += dc.score;
//self.score += dc.score;

// perks
if ( IsDefined( dc.perk ) )
{
oldPerks = dc.perk.size;
if ( oldPerks >= 2 )
{
newPerks = int( oldPerks * 0.5 );

for ( i = 0; i {
if ( self HasPerk( dc.perk[i] ) )
{
continue;
}

remaining = dc.perk.size - i;
if ( remaining 50 )
{
maps\_zombiemode_perks::give_perk( dc.perk[i] );
newPerks--;
}

if ( newPerks == 0 )
{
break;
}
}
}
}

// abilities
//if ( IsDefined( dc.curr_ability ) )
//{
// self maps\_zombiemode_ability::giveAbility( dc.curr_ability );
// self maps\_zombiemode_ability::update_player_ability_status();
//}

if ( maps\_zombiemode_weap_cymbal_monkey::cymbal_monkey_exists() )
{
if ( dc.zombie_cymbal_monkey_count )
{
self giveweapon( "zombie_cymbal_monkey" );
self setweaponammoclip( "zombie_cymbal_monkey", dc.zombie_cymbal_monkey_count );
}
}
}

//-----------------------------------------------------------------------------------
// solo player gets both weapons back and only loses 1 perk
//-----------------------------------------------------------------------------------
deathcard_give_solo()
{
dc = level.deathcards[0];

// perks
self maps\_zombiemode::laststand_giveback_player_perks();

take = true;
startWeapon = dc.weapon[dc.current_weapon];
if ( startWeapon == "m1911_zm" )
{
take = false;
}

currentWeapon = self GetCurrentWeapon();
if ( currentWeapon != "none" && take )
{
self TakeWeapon( currentWeapon );
}

for ( i = 0; i {
if ( IsDefined( dc.weapon[i] ) )
{
weapon = dc.weapon[i];
if ( weapon != "m1911_zm" || take )
{
self GiveWeapon( weapon, 0 );
self SetWeaponAmmoClip( weapon, WeaponClipSize( weapon ) );

self GiveStartAmmo( weapon );
}
}
}

if ( dc.current_weapon >= 0 && take )
{
self SwitchToWeapon( dc.weapon[dc.current_weapon], 0 );
}

// score
//self.old_score += dc.score;
//self.score += dc.score;

// abilities
//if ( IsDefined( dc.curr_ability ) )
//{
// self maps\_zombiemode_ability::giveAbility( dc.curr_ability );
// self maps\_zombiemode_ability::update_player_ability_status();
//}

if ( maps\_zombiemode_weap_cymbal_monkey::cymbal_monkey_exists() )
{
if ( dc.zombie_cymbal_monkey_count )
{
self giveweapon( "zombie_cymbal_monkey" );
self setweaponammoclip( "zombie_cymbal_monkey", dc.zombie_cymbal_monkey_count );
}
}
}

//-----------------------------------------------------------------------------------
// bounce the deathcard around
//-----------------------------------------------------------------------------------
deathcard_wobble()
{
self endon ("deathcard_grabbed");
self endon ("deathcard_timedout");

if (isdefined(self))
{
playfxontag (level._effect["powerup_on"], self, "tag_origin");
self playsound("zmb_spawn_powerup");
self playloopsound("evt_death_card_loop");
}

while (isdefined(self))
{
self rotateyaw( 360, 3, 3, 0 );
wait( 3 );
}
}

//-----------------------------------------------------------------------------------
// time out after end of round
//-----------------------------------------------------------------------------------
deathcard_timeout()
{
self endon ("deathcard_grabbed");

level waittill( "between_round_over" );
wait( 1 );
level waittill( "between_round_over" );

//wait 75;
self hide();

/*
for (i = 0; i {
// hide and show
if (i % 2)
{
self hide();
}
else
{
self show();
}

if (i {
wait 0.5;
}
else if (i {
wait 0.25;
}
else
{
wait 0.1;
}
}
*/

self notify ("deathcard_timedout");
self delete();
}






Zombiemode_Devgui
#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;

/#

init()
{
SetDvar( "zombie_devgui", "" );
SetDvar( "scr_force_weapon", "" );
SetDvar( "scr_zombie_round", "1" );
SetDvar( "scr_zombie_dogs", "1" );
SetDvar( "scr_spawn_tesla", "" );

level thread zombie_devgui_think();
level thread zombie_devgui_tesla_think();
level thread zombie_devgui_thundergun_think();
level thread zombie_devgui_freezegun_think();
}


zombie_devgui_think()
{
for ( ;; )
{
cmd = GetDvar( #"zombie_devgui" );

switch ( cmd )
{
case "money":
players = get_players();
array_thread( players, ::zombie_devgui_give_money );
if ( players.size > 1 )
{
for ( i=0; i {
level.team_pool[i].score += 100000;
level.team_pool[i].old_score += 100000;
level.team_pool[i] maps\_zombiemode_score::set_team_score_hud();
}
}
break;

case "health":
//iprintln( "Mega Health for all players" );
array_thread( get_players(), ::zombie_devgui_give_health );
break;

case "specialty_armorvest":
case "specialty_quickrevive":
case "specialty_fastreload":
case "specialty_rof":
case "specialty_threeprimaries":
zombie_devgui_give_perk( cmd );
break;

case "nuke":
case "insta_kill":
case "double_points":
case "full_ammo":
case "carpenter":
case "fire_sale":
case "bonfire_sale":
case "minigun":
zombie_devgui_give_powerup( cmd );
break;

case "round":
zombie_devgui_goto_round( GetDvarInt( #"scr_zombie_round" ) );
break;
case "round_next":
zombie_devgui_goto_round( level.round_number + 1 );
break;
case "round_prev":
zombie_devgui_goto_round( level.round_number - 1 );
break;

case "chest_move":
if ( IsDefined( level.chest_accessed ) )
{
//iprintln( "Teddy bear will spawn on next open" );
level notify( "devgui_chest_end_monitor" );
level.chest_accessed = 100;
}
break;

case "chest_never_move":
if ( IsDefined( level.chest_accessed ) )
{
//iprintln( "Setting chest to never move" );
level thread zombie_devgui_chest_never_move();
}
break;

case "chest":
if( IsDefined( level.zombie_weapons[ GetDvar( #"scr_force_weapon" ) ] ) )
{
//iprintln( GetDvar( #"scr_force_weapon" ) + " will spawn on next open" );
}
break;

case "give_monkey":
array_thread( get_players(), ::zombie_devgui_give_monkey );
break;

case "ape_round":
zombie_devgui_ape_round();
break;

case "thief_round":
zombie_devgui_thief_round();
break;

case "dog_round":
zombie_devgui_dog_round( GetDvarInt( #"scr_zombie_dogs" ) );
break;

case "dog_round_skip":
zombie_devgui_dog_round_skip();
break;

case "print_variables":
zombie_devgui_dump_zombie_vars();
break;

case "revive_all":
zombie_devgui_revive_all();
break;

case "power_on":
flag_set( "power_on" );
Objective_State(8,"done");
break;

//case "zombie_airstrike":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_artillery":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_napalm":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_helicopter":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_turret":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_portal":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_dogs":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_rcbomb":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_cloak":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;
//
//case "zombie_endurance":
// array_thread( get_players(), ::zombie_devgui_give_ability, cmd );
// break;

case "":
break;

default:
if ( IsDefined( level.custom_devgui ) )
{
[[level.custom_devgui]]( cmd );
}
else
{
//iprintln( "Unknown devgui command: '" + cmd + "'" );
}
break;
}

SetDvar( "zombie_devgui", "" );
wait( 0.5 );
}
}


zombie_devgui_tesla_think()
{
if ( !maps\_zombiemode_weapons::is_weapon_included( "tesla_gun_zm" ) )
{
return;
}

SetDvar( "scr_tesla_max_arcs", level.zombie_vars["tesla_max_arcs"] );
SetDvar( "scr_tesla_max_enemies", level.zombie_vars["tesla_max_enemies_killed"] );
SetDvar( "scr_tesla_radius_start", level.zombie_vars["tesla_radius_start"] );
SetDvar( "scr_tesla_radius_decay", level.zombie_vars["tesla_radius_decay"] );
SetDvar( "scr_tesla_head_gib_chance", level.zombie_vars["tesla_head_gib_chance"] );
SetDvar( "scr_tesla_arc_travel_time", level.zombie_vars["tesla_arc_travel_time"] );

for ( ;; )
{
level.zombie_vars["tesla_max_arcs"] = GetDvarInt( #"scr_tesla_max_arcs" );
level.zombie_vars["tesla_max_enemies_killed"] = GetDvarInt( #"scr_tesla_max_enemies" );
level.zombie_vars["tesla_radius_start"] = GetDvarInt( #"scr_tesla_radius_start" );
level.zombie_vars["tesla_radius_decay"] = GetDvarInt( #"scr_tesla_radius_decay" );
level.zombie_vars["tesla_head_gib_chance"] = GetDvarInt( #"scr_tesla_head_gib_chance" );
level.zombie_vars["tesla_arc_travel_time"] = GetDvarFloat( #"scr_tesla_arc_travel_time" );

wait( 0.5 );
}
}


zombie_devgui_thundergun_think()
{
if ( !maps\_zombiemode_weapons::is_weapon_included( "thundergun_zm" ) )
{
return;
}

SetDvar( "scr_thundergun_cylinder_radius", level.zombie_vars["thundergun_cylinder_radius"] );
SetDvar( "scr_thundergun_fling_range", level.zombie_vars["thundergun_fling_range"] );
SetDvar( "scr_thundergun_gib_range", level.zombie_vars["thundergun_gib_range"] );
SetDvar( "scr_thundergun_gib_damage", level.zombie_vars["thundergun_gib_damage"] );
SetDvar( "scr_thundergun_knockdown_range", level.zombie_vars["thundergun_knockdown_range"] );
SetDvar( "scr_thundergun_knockdown_damage", level.zombie_vars["thundergun_knockdown_damage"] );

for ( ;; )
{
level.zombie_vars["thundergun_cylinder_radius"] = GetDvarInt( #"scr_thundergun_cylinder_radius" );
level.zombie_vars["thundergun_fling_range"] = GetDvarInt( #"scr_thundergun_fling_range" );
level.zombie_vars["thundergun_gib_range"] = GetDvarInt( #"scr_thundergun_gib_range" );
level.zombie_vars["thundergun_gib_damage"] = GetDvarInt( #"scr_thundergun_gib_damage" );
level.zombie_vars["thundergun_knockdown_range"] = GetDvarInt( #"scr_thundergun_knockdown_range" );
level.zombie_vars["thundergun_knockdown_damage"] = GetDvarInt( #"scr_thundergun_knockdown_damage" );

wait( 0.5 );
}
}


zombie_devgui_freezegun_think()
{
if ( !maps\_zombiemode_weapons::is_weapon_included( "freezegun_zm" ) )
{
return;
}

SetDvar( "scr_freezegun_cylinder_radius", level.zombie_vars["freezegun_cylinder_radius"] );
SetDvar( "scr_freezegun_inner_range", level.zombie_vars["freezegun_inner_range"] );
SetDvar( "scr_freezegun_outer_range", level.zombie_vars["freezegun_outer_range"] );
SetDvar( "scr_freezegun_inner_damage", level.zombie_vars["freezegun_inner_damage"] );
SetDvar( "scr_freezegun_outer_damage", level.zombie_vars["freezegun_outer_damage"] );
SetDvar( "scr_freezegun_shatter_range", level.zombie_vars["freezegun_shatter_range"] );
SetDvar( "scr_freezegun_shatter_inner_damage", level.zombie_vars["freezegun_shatter_inner_damage"] );
SetDvar( "scr_freezegun_shatter_outer_damage", level.zombie_vars["freezegun_shatter_outer_damage"] );
SetDvar( "scr_freezegun_cylinder_radius_upgraded", level.zombie_vars["freezegun_cylinder_radius_upgraded"] );
SetDvar( "scr_freezegun_inner_range_upgraded", level.zombie_vars["freezegun_inner_range_upgraded"] );
SetDvar( "scr_freezegun_outer_range_upgraded", level.zombie_vars["freezegun_outer_range_upgraded"] );
SetDvar( "scr_freezegun_inner_damage_upgraded", level.zombie_vars["freezegun_inner_damage_upgraded"] );
SetDvar( "scr_freezegun_outer_damage_upgraded", level.zombie_vars["freezegun_outer_damage_upgraded"] );
SetDvar( "scr_freezegun_shatter_range_upgraded", level.zombie_vars["freezegun_shatter_range_upgraded"] );
SetDvar( "scr_freezegun_shatter_inner_damage_upgraded", level.zombie_vars["freezegun_shatter_inner_damage_upgraded"] );
SetDvar( "scr_freezegun_shatter_outer_damage_upgraded", level.zombie_vars["freezegun_shatter_outer_damage_upgraded"] );

for ( ;; )
{
level.zombie_vars["freezegun_cylinder_radius"] = GetDvarInt( #"scr_freezegun_cylinder_radius" );
level.zombie_vars["freezegun_inner_range"] = GetDvarInt( #"scr_freezegun_inner_range" );
level.zombie_vars["freezegun_outer_range"] = GetDvarInt( #"scr_freezegun_outer_range" );
level.zombie_vars["freezegun_inner_damage"] = GetDvarInt( #"scr_freezegun_inner_damage" );
level.zombie_vars["freezegun_outer_damage"] = GetDvarInt( #"scr_freezegun_outer_damage" );
level.zombie_vars["freezegun_shatter_range"] = GetDvarInt( #"scr_freezegun_shatter_range" );
level.zombie_vars["freezegun_shatter_inner_damage"] = GetDvarInt( #"scr_freezegun_shatter_inner_damage" );
level.zombie_vars["freezegun_shatter_outer_damage"] = GetDvarInt( #"scr_freezegun_shatter_outer_damage" );
level.zombie_vars["freezegun_cylinder_radius_upgraded"] = GetDvarInt( #"scr_freezegun_cylinder_radius_upgraded" );
level.zombie_vars["freezegun_inner_range_upgraded"] = GetDvarInt( #"scr_freezegun_inner_range_upgraded" );
level.zombie_vars["freezegun_outer_range_upgraded"] = GetDvarInt( #"scr_freezegun_outer_range_upgraded" );
level.zombie_vars["freezegun_inner_damage_upgraded"] = GetDvarInt( #"scr_freezegun_inner_damage_upgraded" );
level.zombie_vars["freezegun_outer_damage_upgraded"] = GetDvarInt( #"scr_freezegun_outer_damage_upgraded" );
level.zombie_vars["freezegun_shatter_range_upgraded"] = GetDvarInt( #"scr_freezegun_shatter_range_upgraded" );
level.zombie_vars["freezegun_shatter_inner_damage_upgraded"] = GetDvarInt( #"scr_freezegun_shatter_inner_damage_upgraded" );
level.zombie_vars["freezegun_shatter_outer_damage_upgraded"] = GetDvarInt( #"scr_freezegun_shatter_outer_damage_upgraded" );

wait( 0.5 );
}
}


zombie_devgui_give_money()
{
assert( IsDefined( self ) );
assert( IsPlayer( self ) );
assert( IsAlive( self ) );

self maps\_zombiemode_score::add_to_player_score( 100000 );
}


zombie_devgui_give_monkey()
{
self notify( "new monkey thread" );
self endon( "new monkey thread" );

assert( IsDefined( self ) );
assert( IsPlayer( self ) );
assert( IsAlive( self ) );

self maps\_zombiemode_weap_cymbal_monkey::player_give_cymbal_monkey();
while( true )
{
self GiveMaxAmmo( "zombie_cymbal_monkey" );
wait( 1 );
}
}


zombie_devgui_give_health()
{
assert( IsDefined( self ) );
assert( IsPlayer( self ) );
assert( IsAlive( self ) );

self notify( "devgui_health" );
self endon( "devgui_health" );
self endon( "disconnect" );
self endon( "death" );

while ( 1 )
{
self.maxhealth = 100000;
self.health = 100000;

self waittill_any( "player_revived", "perk_used", "spawned_player" );
wait( 2 );
}
}


zombie_devgui_give_perk( perk )
{
vending_triggers = GetEntArray( "zombie_vending", "targetname" );
player = get_players()[0];

if ( vending_triggers.size {
//iprintln( "Map does not contain any perks machines" );
return;
}

for ( i = 0; i {
if ( vending_triggers[i].script_noteworthy == perk )
{
vending_triggers[i] notify( "trigger", player );
return;
}
}

//iprintln( "Map does not contain perks machine with perk: " + perk );
}


//zombie_devgui_give_ability( ability )
//{
// self maps\_zombiemode_ability::give_ability_now( ability );
//}


zombie_devgui_give_powerup( powerup_name )
{
player = get_players()[0];
found = false;

for ( i = 0; i {
if ( level.zombie_powerup_array[i] == powerup_name )
{
level.zombie_powerup_index = i;
found = true;
break;
}
}

if ( !found )
{
//iprintln( "Powerup not found: " + powerup_name );
return;
}

// Trace to where the player is looking
direction = player GetPlayerAngles();
direction_vec = AnglesToForward( direction );
eye = player GetEye();

scale = 8000;
direction_vec = (direction_vec[0] * scale, direction_vec[1] * scale, direction_vec[2] * scale);

// offset 2 units on the Z to fix the bug where it would drop through the ground sometimes
trace = bullettrace( eye, eye + direction_vec, 0, undefined );
level.zombie_devgui_power = 1;
level.zombie_vars["zombie_drop_item"] = 1;
level.powerup_drop_count = 0;
level thread maps\_zombiemode_powerups::powerup_drop( trace["position"] );


}


zombie_devgui_goto_round( target_round )
{
player = get_players()[0];

if ( target_round {
target_round = 1;
}

level.zombie_total = 0;
maps\_zombiemode::ai_calculate_health( target_round );
level.round_number = target_round - 1;

level notify( "kill_round" );

// fix up the hud
// if( IsDefined( level.chalk_hud2 ) )
// {
// level.chalk_hud2 maps\_zombiemode_utility::destroy_hud();
//
// if ( level.round_number // {
// level.chalk_hud2 = maps\_zombiemode::create_chalk_hud( 64 );
// }
// }
//
// if ( IsDefined( level.chalk_hud1 ) )
// {
// level.chalk_hud1 maps\_zombiemode_utility::destroy_hud();
// level.chalk_hud1 = maps\_zombiemode::create_chalk_hud();
//
// switch( level.round_number )
// {
// case 0:
// case 1:
// level.chalk_hud1 SetShader( "hud_chalk_1", 64, 64 );
// break;
// case 2:
// level.chalk_hud1 SetShader( "hud_chalk_2", 64, 64 );
// break;
// case 3:
// level.chalk_hud1 SetShader( "hud_chalk_3", 64, 64 );
// break;
// case 4:
// level.chalk_hud1 SetShader( "hud_chalk_4", 64, 64 );
// break;
// default:
// level.chalk_hud1 SetShader( "hud_chalk_5", 64, 64 );
// break;
// }
// }

//iprintln( "Jumping to round: " + target_round );
wait( 1 );

// kill all active zombies
zombies = GetAiSpeciesArray( "axis", "all" );

if ( IsDefined( zombies ) )
{
for (i = 0; i {
zombies[i] dodamage(zombies[i].health + 666, zombies[i].origin);
}
}
}


zombie_devgui_ape_round()
{
if ( IsDefined( level.next_ape_round ) )
{
zombie_devgui_goto_round( level.next_ape_round );
}
}

zombie_devgui_thief_round()
{
if ( IsDefined( level.next_thief_round ) )
{
zombie_devgui_goto_round( level.next_thief_round );
}
}

zombie_devgui_dog_round( num_dogs )
{
if( !IsDefined( level.dogs_enabled ) || !level.dogs_enabled )
{
//iprintln( "Dogs not enabled in this map" );
return;
}

if( !IsDefined( level.dog_rounds_enabled ) || !level.dog_rounds_enabled )
{
//iprintln( "Dog rounds not enabled in this map" );
return;
}

if( !IsDefined( level.enemy_dog_spawns ) || level.enemy_dog_spawns.size {
//iprintln( "Dog spawners not found in this map" );
return;
}

if ( !flag( "dog_round" ) )
{
//iprintln( "Spawning " + num_dogs + " dogs" );
SetDvar( "force_dogs", num_dogs );
}
else
{
//iprintln( "Removing dogs" );
}

zombie_devgui_goto_round( level.round_number + 1 );
}

zombie_devgui_dog_round_skip()
{
if ( IsDefined( level.next_dog_round ) )
{
zombie_devgui_goto_round( level.next_dog_round );
}
}


zombie_devgui_dump_zombie_vars()
{
if ( !IsDefined( level.zombie_vars ) )
{
return;
}


if( level.zombie_vars.size > 0 )
{
//iprintln( "Zombie Variables Sent to Console" );
println( "##### Zombie Variables #####");
}
else
{
return;
}

var_names = GetArrayKeys( level.zombie_vars );

for( i = 0; i {
key = var_names[i];
println( key + ": " + level.zombie_vars[key] );
}

println( "##### End Zombie Variables #####");
}


zombie_devgui_revive_all()
{
players = get_players();
reviver = players[0];

for ( i = 0; i {
if ( !players[i] maps\_laststand::player_is_in_laststand() )
{
reviver = players[i];
break;
}
}

for ( i = 0; i {
if ( players[i] maps\_laststand::player_is_in_laststand() )
{
players[i] maps\_laststand::revive_force_revive( reviver );
players[i] notify ( "zombified" );
}
}
}


zombie_devgui_chest_never_move()
{
level notify( "devgui_chest_end_monitor" );
level endon( "devgui_chest_end_monitor" );

for ( ;; )
{
level.chest_accessed = 0;
wait( 5 );
}
}


#/

Link to comment

Zombiemode_Load

#include common_scripts\utility;
#include maps\_utility;
//#include maps\_debug;
#include maps\_hud_util;
#include maps\_load_common;

#using_animtree("generic_human");

main( bScriptgened,bCSVgened,bsgenabled )
{
/*------------------------------------------------ spawnflags ---------------*/

level.SPAWNFLAG_MODEL_DYNAMIC_PATH = 1;

level.SPAWNFLAG_TRIGGER_AI_AXIS = 1;
level.SPAWNFLAG_TRIGGER_AI_ALLIES = 2;
level.SPAWNFLAG_TRIGGER_AI_NEUTRAL = 4;
level.SPAWNFLAG_TRIGGER_NOT_PLAYER = 8;
level.SPAWNFLAG_TRIGGER_VEHICLE = 16;
level.SPAWNFLAG_TRIGGER_SPAWN = 32;
level.SPAWNFLAG_TRIGGER_TOUCH_ONCE = 64;
level.SPAWNFLAG_TRIGGER_SPAWN_MANAGER = 512;
level.SPAWNFLAG_TRIGGER_TRIGGER_ONCE = 1024;

level.SPAWNFLAG_ACTOR_SPAWNER = 1;
level.SPAWNFLAG_ACTOR_SCRIPTFORCESPAWN = 16;
level.SPAWNFLAG_ACTOR_SM_PRIORITY = 32;

level.SPAWNFLAG_VEHICLE_NODE_START_NODE = 1;

level.SPAWNFLAG_VEHICLE_USEABLE = 1;
level.SPAWNFLAG_VEHICLE_SPAWNER = 2;

level.SPAWNFLAG_TURRET_PREPLACED = 1;

level.SPAWNFLAG_PATH_NOT_CHAIN = 2;
level.SPAWNFLAG_PATH_DONT_STAND = 4;
level.SPAWNFLAG_PATH_DONT_CROUCH = 8;
level.SPAWNFLAG_PATH_DONT_PRONE = 16;
level.SPAWNFLAG_PATH_DISABLED = 512;
level.SPAWNFLAG_PATH_DONT_LEFT = 1024;
level.SPAWNFLAG_PATH_BALCONY = 1024;
level.SPAWNFLAG_PATH_DONT_RIGHT = 2048;
level.SPAWNFLAG_PATH_BALCONY_NORAILING = 2048;

/*-------------------------------------------------------------------------*/

println( "_LOAD START TIME = " + GetTime() );
/#
debug_replay( "File: _zombiemode_load.gsc. Function: main()\n" );
#/

register_overloaded_func( "animscripts\traverse\shared", "init_traverse", animscripts\traverse\zombie_shared::init_traverse );

set_early_level();

animscripts\weaponList::precacheclipfx();
animscripts\weaponList::precacheWeaponSwitchFx();

animscripts\revive::precacheReviveModels();

maps\_constants::main();

// Setup animations for doing hand signals with the _utility function
level.scr_anim[ "generic" ][ "signal_onme" ] = %CQB_stand_wave_on_me;
level.scr_anim[ "generic" ][ "signal_go" ] = %CQB_stand_wave_go_v1;
level.scr_anim[ "generic" ][ "signal_stop" ] = %CQB_stand_signal_stop;
level.scr_anim[ "generic" ][ "signal_moveup" ] = %CQB_stand_signal_move_up;
level.scr_anim[ "generic" ][ "signal_moveout" ] = %CQB_stand_signal_move_out;

if( !IsDefined( level.script_gen_dump_reasons ) )
{
level.script_gen_dump_reasons = [];
}
if( !IsDefined( bsgenabled ) )
{
level.script_gen_dump_reasons[level.script_gen_dump_reasons.size] = "First run";
}
if( !IsDefined( bCSVgened ) )
{
bCSVgened = false;
}
level.bCSVgened = bCSVgened;

if( !IsDefined( bScriptgened ) )
{
bScriptgened = false;
}
else
{
bScriptgened = true;
}
level.bScriptgened = bScriptgened;

/#
ascii_logo();
#/

if( GetDvar( #"debug" ) == "" )
{
SetDvar( "debug", "0" );
}

if( GetDvar( #"fallback" ) == "" )
{
SetDvar( "fallback", "0" );
}

if( GetDvar( #"angles" ) == "" )
{
SetDvar( "angles", "0" );
}

if( GetDvar( #"noai" ) == "" )
{
SetDvar( "noai", "off" );
}

if( GetDvar( #"scr_RequiredMapAspectratio" ) == "" )
{
SetDvar( "scr_RequiredMapAspectratio", "1" );
}

CreatePrintChannel( "script_debug" );

if( !IsDefined( anim.notetracks ) )
{
// string based array for notetracks
anim.notetracks = [];
animscripts\zombie_shared::registerNoteTracks();
}

level._loadStarted = true;
level.first_frame = true;
level.level_specific_dof = false;

// CODER_MOD
// DSL - 05/21/08 - Set to true when all players have connected to the game.
//level._players_connected = false;
flag_init( "all_players_connected" );
flag_init( "all_players_spawned" );
flag_init( "drop_breadcrumbs");
flag_set( "drop_breadcrumbs" );

thread remove_level_first_frame();

level.wait_any_func_array = [];
level.run_func_after_wait_array = [];
level.do_wait_endons_array = [];

level.script = Tolower( GetDvar( #"mapname" ) );
level.radiation_totalpercent = 0;

level.clientscripts = ( GetDvar( #"cg_usingClientScripts" ) != "" );;

level._client_exploders = [];
level._client_exploder_ids = [];

registerClientSys( "levelNotify" );
registerClientSys( "lsm" );
registerClientSys( "box_indicator" );

flag_init( "missionfailed" );
flag_init( "auto_adjust_initialized" );
flag_init( "global_hint_in_use" );

// MikeD( 12/15/2007 ): IW abandoned this feature( auto-adjust )
//thread maps\_gameskill::aa_init_stats();

// MikeD( 12/15/2007 ): Doesn't appear to do anything...
// thread player_death_detection();

level.default_run_speed = 190;
SetSavedDvar( "g_speed", level.default_run_speed );

//maps\_gamemode::setup();

SetSavedDvar( "sv_saveOnStartMap", maps\_gamemode::shouldSaveOnStartup() );

level.dronestruct = [];
struct_class_init();

if( !IsDefined( level.flag ) )
{
level.flag = [];
level.flags_lock = [];
}
else
{
// flags initialized before this should be checked for stat tracking
flags = GetArrayKeys( level.flag );
array_levelthread( flags, ::check_flag_for_stat_tracking );
}

// can be turned on and off to control friendly_respawn_trigger
flag_init( "respawn_friendlies" );
flag_init( "player_flashed" );

// for script gen
flag_init( "scriptgen_done" );
level.script_gen_dump_reasons = [];
if( !IsDefined( level.script_gen_dump ) )
{
level.script_gen_dump = [];
level.script_gen_dump_reasons[0] = "First run";
}

if( !IsDefined( level.script_gen_dump2 ) )
{
level.script_gen_dump2 = [];
}

if( IsDefined( level.createFXent ) )
{
script_gen_dump_addline( "maps\\createfx\\"+level.script+"_fx::main(); ", level.script+"_fx" ); // adds to scriptgendump
}

if( IsDefined( level.script_gen_dump_preload ) )
{
for( i = 0; i {
script_gen_dump_addline( level.script_gen_dump_preload[i].string, level.script_gen_dump_preload[i].signature );
}
}

// level.aim_delay_off = false;
// level.last_wait_spread = -1;
level.last_mission_sound_time = -5000;

// MikeD( 9/4/2007 ): These 2 arrays are needed for _colors.
level.hero_list = [];
level.ai_array = [];
thread precache_script_models();

// SCRIPT_MOD
// these are head icons so you can see who the players are
PrecacheHeadIcon( "headicon_american" );

/#
PrecacheModel( "fx" );
// PrecacheModel( "temp" );
#/
PrecacheModel( "tag_origin" );
PrecacheModel( "tag_origin_animate" );
PrecacheShellShock( "level_end" );
PrecacheShellShock( "default" );
PrecacheShellShock( "flashbang" );
PrecacheShellShock( "dog_bite" );
PrecacheShellShock( "pain" );
PrecacheRumble( "damage_heavy" );
precacherumble( "dtp_rumble" );
precacherumble( "slide_rumble" );
PrecacheRumble( "damage_light" );
PrecacheRumble( "grenade_rumble" );
PrecacheRumble( "artillery_rumble" );
PrecacheRumble( "reload_small" );
PrecacheRumble( "reload_medium" );
PrecacheRumble( "reload_large" );
PrecacheRumble( "reload_clipin" );
PrecacheRumble( "reload_clipout" );
PrecacheRumble( "reload_rechamber" );
PrecacheRumble( "pullout_small" );

PrecacheString( &"GAME_GET_TO_COVER" );
PrecacheString( &"SCRIPT_GRENADE_DEATH" );
PrecacheString( &"SCRIPT_GRENADE_SUICIDE_LINE1" );
PrecacheString( &"SCRIPT_GRENADE_SUICIDE_LINE2" );
PrecacheString( &"SCRIPT_EXPLODING_VEHICLE_DEATH" );
PrecacheString( &"SCRIPT_EXPLODING_BARREL_DEATH" );
PrecacheString( &"STARTS_AVAILABLE_STARTS" );
PrecacheString( &"STARTS_CANCEL" );
PrecacheString( &"STARTS_DEFAULT" );
if ( GetDvar( #"zombiemode" ) != "1" )
{
PreCacheShader( "overlay_low_health_splat" );
}
PrecacheShader( "overlay_low_health" );
PrecacheShader( "overlay_low_health_compass" );
PrecacheShader( "hud_grenadeicon" );
PrecacheShader( "hud_grenadepointer" );
PrecacheShader( "hud_burningcaricon" );
PrecacheShader( "hud_burningbarrelicon" );
PrecacheShader( "black" );
PrecacheShader( "white" );

PreCacheShellShock( "death" );
PreCacheShellShock( "explosion" );
PreCacheShellShock( "tank_mantle" );
// PreCacheShellShock( "quagmire_window_break" );

// If gamemode calls for it, precache optional assets here.
if(isdefined(level._gamemode_precache))
{
[[level._gamemode_precache]]();
}

// MikeD( 10/30/2007 ): Defaulting water off
WaterSimEnable( false );

level.createFX_enabled = ( GetDvar( #"createfx" ) != "" );

maps\_cheat::init();

maps\_mgturret::main();
maps\_mgturret::setdifficulty();

setupExploders();
maps\_art::main();
thread maps\_vehicle::init_vehicles();

maps\_anim::init();

thread maps\_createfx::fx_init();
if( level.createFX_enabled )
{
maps\_callbackglobal::init();
maps\_callbacksetup::SetupCallbacks();
calculate_map_center();

maps\_loadout::init_loadout(); // MikeD: Just to set the level.campaign

level thread all_players_connected();
level thread all_players_spawned();
thread maps\_introscreen::main();
maps\_createfx::createfx();
}

if ( !isDefined(level.zombietron_mode) )
{
maps\_weapons::init();
maps\_detonategrenades::init();
thread maps\_flareWeapon::init();
}

thread setup_simple_primary_lights();

// MikeD( 10/28/2007 3:06:12 ): Precache Gib FX
animscripts\zombie_death::precache_gib_fx();

// --------------------------------------------------------------------------------
// ---- PAST THIS POINT THE SCRIPTS DONT RUN WHEN GENERATING REFLECTION PROBES ----
// --------------------------------------------------------------------------------

/#
if( GetDvar( #"r_reflectionProbeGenerate" ) == "1" )
{
maps\_global_fx::main();
maps\_loadout::init_loadout(); // MikeD: Just to set the level.campaign
level waittill( "eternity" );
}
#/

if( GetDvar( #"g_connectpaths" ) == "2" )
{
/# println( "g_connectpaths == 2; halting script execution" ); #/
level waittill( "eternity" );
}

println( "level.script: ", level.script );

// CODE_MOD
maps\_callbackglobal::init();
maps\_callbacksetup::SetupCallbacks();

// If gamemode calls for it, override callbacks as needed here.
if(isdefined(level._gamemode_initcallbacks))
{
[[level._gamemode_initcallbacks]]();
}

maps\_autosave::main();
maps\_anim::init();
maps\_busing::businit();
maps\_music::music_init();
maps\_dds::dds_init();
/#
thread maps\_radiant_live_update::main();
#/
// AI revive feature - turned on by default in any level.
if(!IsDefined(level.reviveFeature))
level.reviveFeature = true;

// legacy... necessary?
anim.useFacialAnims = false;

if( !IsDefined( level.missionfailed ) )
{
level.missionfailed = false;
}

// set the blindfire timers, these can be overridden by the script later on.
if( !IsDefined( level.blindfireTimeMin ) )
{
level.blindfireTimeMin = 3000;
}

if( !IsDefined( level.blindfireTimeMax ) )
{
level.blindfireTimeMax = 12000;
}

if( !IsDefined( level.secondBlindfireChance ) )
{
level.secondBlindfireChance = 50;
}

if(isDefined(level.skill_override))
{
maps\_gameskill::setSkill(undefined,level.skill_override);
}
else
{
maps\_gameskill::setSkill();
}

maps\_loadout::init_loadout();
maps\_destructible::init();
//maps\_ai_supplements::init_ai_supplements();
// removing coop challenges for now MGORDON
// maps\_challenges_coop::init();
maps\_hud_message::init();
SetObjectiveTextColors();
if ( !isDefined(level.zombietron_mode) )
{
maps\_laststand::init();
}
// CODE_MOD
thread maps\_cooplogic::init();
thread maps\_ingamemenus::init();
calculate_map_center();

// global effects for objects
maps\_global_fx::main();

//thread devhelp(); // disabled due to localization errors

// CODER_MOD
// moved from _loadout::give_loadout()
if( !IsDefined( level.campaign ) )
{
level.campaign = "american";
}

if ( GetDvar( #"zombiemode" ) != "1" )
{
maps\_contextual_melee::setup();
}

SetSavedDvar( "ui_campaign", level.campaign ); // level.campaign is set in maps\_loadout::init_loadout

/#
thread maps\_debug::mainDebug();
#/

// SCRIPTER_MOD
// MikeD( 3/20/2007 ): Added for _createcam to work.
/#
// commented out prevent variable limit being hit
//maps\_createcam::main();
maps\_createdynents::init_once();
thread maps\_createdynents::main();
#/

// MikeD( 7/27/2007 ): Added the SaveGame here for the beginning of the level.
if( GetDvar( #"sv_saveOnStartMap" ) == "1" )
{
level thread maps\_autosave::start_level_save();
}

// CODER_MOD
// DSL - 05/21/08 - All players have connected mechanism.
level thread all_players_connected();
level thread all_players_spawned();
thread maps\_introscreen::main();

thread maps\_minefields::main();
// thread maps\_shutter::main();
// thread maps\_breach::main();
// thread maps\_inventory::main();
// thread maps\_photosource::main();
thread maps\_endmission::main();
maps\_friendlyfire::main();

// For _anim to track what animations have been used. Uncomment this locally if you need it.
// thread usedAnimations();

array_levelthread( GetEntArray( "badplace", "targetname" ), ::badplace_think );

array_delete(GetEntArray( "delete_on_load", "targetname" ));

setup_traversals();

// SCRIPTER_MOD: dguzzo: 3/24/2009 : need these anymore?
// array_thread( GetEntArray( "piano_key", "targetname" ), ::pianoThink );
// array_thread( GetEntArray( "piano_damage", "targetname" ), ::pianoDamageThink );
array_thread( GetEntArray( "water", "targetname" ), ::waterThink );

thread maps\_audio::main();
// CODER_MOD
// Droche 01/28/09 moved to last stand
// no longer needed
//thread maps\_revive::main();

// this has to come before _spawner moves the turrets around
thread massNodeInitFunctions();

// Various newvillers globalized scripts
flag_init( "spawning_friendlies" );
flag_init( "friendly_wave_spawn_enabled" );
flag_clear( "spawning_friendlies" );

level.spawn_funcs = [];
level.spawn_funcs["allies"] = [];
level.spawn_funcs["axis"] = [];
level.spawn_funcs["neutral"] = [];

thread maps\_spawner::goalVolumes();

level.trigger_hint_string = [];
level.trigger_hint_func = [];
level.fog_trigger_current = undefined;

if( !IsDefined( level.trigger_flags ) )
{
// may have been defined by AI spawning
init_trigger_flags();
}

trigger_funcs = [];
trigger_funcs["flood_spawner"] = maps\_spawner::flood_trigger_think;
trigger_funcs["trigger_spawner"] = maps\_spawner::trigger_spawner;
trigger_funcs["trigger_autosave"] = maps\_autosave::trigger_autosave;
trigger_funcs["autosave_now"] = maps\_autosave::autosave_now_trigger;
trigger_funcs["trigger_unlock"] = ::trigger_unlock;
trigger_funcs["trigger_lookat"] = ::trigger_lookat;
trigger_funcs["trigger_looking"] = ::trigger_looking;
trigger_funcs["trigger_cansee"] = ::trigger_cansee;
trigger_funcs["flag_set"] = ::flag_set_trigger;
trigger_funcs["flag_clear"] = ::flag_clear_trigger;
trigger_funcs["flag_on_cleared"] = ::flag_on_cleared;
trigger_funcs["flag_set_touching"] = ::flag_set_touching;
trigger_funcs["objective_event"] = maps\_spawner::objective_event_init;
trigger_funcs["friendly_respawn_trigger"] = ::friendly_respawn_trigger;
trigger_funcs["friendly_respawn_clear"] = ::friendly_respawn_clear;
trigger_funcs["trigger_ignore"] = ::trigger_ignore;
trigger_funcs["trigger_pacifist"] = ::trigger_pacifist;
trigger_funcs["trigger_delete"] = ::trigger_turns_off;
trigger_funcs["trigger_delete_on_touch"] = ::trigger_delete_on_touch;
trigger_funcs["trigger_off"] = ::trigger_turns_off;
trigger_funcs["trigger_outdoor"] = maps\_spawner::outdoor_think;
trigger_funcs["trigger_indoor"] = maps\_spawner::indoor_think;
trigger_funcs["trigger_hint"] = ::trigger_hint;
trigger_funcs["trigger_grenade_at_player"] = ::throw_grenade_at_player_trigger;
trigger_funcs["delete_link_chain"] = ::delete_link_chain;
trigger_funcs["trigger_fog"] = ::trigger_fog;
// trigger_funcs["trigger_coop_warp"] = maps\_utility::trigger_coop_warp;
trigger_funcs["no_crouch_or_prone"] = ::no_crouch_or_prone_think;
trigger_funcs["no_prone"] = ::no_prone_think;

// trigger_multiple and trigger_radius can have the trigger_spawn flag set
trigger_multiple = GetEntArray( "trigger_multiple", "classname" );
trigger_radius = GetEntArray( "trigger_radius", "classname" );
trigger_once = GetEntArray( "trigger_once", "classname" );

triggers = array_merge( trigger_multiple, trigger_radius );
triggers = array_merge( triggers, trigger_once );

for( i = 0; i {
if( triggers[i] has_spawnflag(level.SPAWNFLAG_TRIGGER_SPAWN) )
{
thread maps\_spawner::trigger_spawner( triggers[i] );
}
}

trigger_types = array(
"trigger_multiple",
"trigger_once",
"trigger_use",
"trigger_use_touch",
"trigger_radius",
"trigger_lookat",
"trigger_damage"
);


for( p = 0; p {
triggertype = trigger_types[p];
triggers = GetEntArray( triggertype, "classname" );

for( i = 0; i {
if ((triggertype != "trigger_once") && triggers[i] has_spawnflag(level.SPAWNFLAG_TRIGGER_TRIGGER_ONCE))
{
level thread trigger_once(triggers[i]);
}

if( IsDefined( triggers[i].script_flag_true ) )
{
level thread script_flag_true_trigger( triggers[i] );
}

if( IsDefined( triggers[i].script_flag_set ) )
{
level thread flag_set_trigger( triggers[i], triggers[i].script_flag_set );
}

if( IsDefined( triggers[i].script_flag_clear ) )
{
level thread flag_clear_trigger( triggers[i], triggers[i].script_flag_clear );
}

if( IsDefined( triggers[i].script_flag_false ) )
{
level thread script_flag_false_trigger( triggers[i] );
}

if( IsDefined( triggers[i].script_autosavename ) || IsDefined( triggers[i].script_autosave ) )
{
level thread maps\_autosave::autosave_name_think( triggers[i] );
}

if( IsDefined( triggers[i].script_fallback ) )
{
level thread maps\_spawner::fallback_think( triggers[i] );
}

if( IsDefined( triggers[i].script_mgTurretauto ) )
{
level thread maps\_mgturret::mgTurret_auto( triggers[i] );
}

if( IsDefined( triggers[i].script_killspawner ) )
{
level thread maps\_spawner::kill_spawner_trigger( triggers[i] );
}

if( IsDefined( triggers[i].script_emptyspawner ) )
{
level thread maps\_spawner::empty_spawner( triggers[i] );
}

if( IsDefined( triggers[i].script_prefab_exploder ) )
{
triggers[i].script_exploder = triggers[i].script_prefab_exploder;
}

if( IsDefined( triggers[i].script_exploder ) )
{
level thread exploder_load( triggers[i] );
}

if( IsDefined( triggers[i].script_bctrigger ) )
{
level thread bctrigger( triggers[i] );
}

if( IsDefined( triggers[i].script_trigger_group ) )
{
triggers[i] thread trigger_group();
}

// MikeD( 06/26/07 ): Added script_notify, which will send out the value set to script_notify as a level notify once triggered
if( IsDefined( triggers[i].script_notify ) )
{
level thread trigger_notify( triggers[i], triggers[i].script_notify );
}

if( IsDefined( triggers[i].targetname ) )
{
// do targetname specific functions
targetname = triggers[i].targetname;
if( IsDefined( trigger_funcs[targetname] ) )
{
level thread[[trigger_funcs[targetname]]]( triggers[i] );
}
}
}
}

// SJ ( 2/15/2010 ) Updates script_forcespawn KVP based on the SPAWNFLAG_ACTOR_SCRIPTFORCESPAWN
// flag for later use in _spawner and other functions of the script
update_script_forcespawn_based_on_flags();

// BB (4.24.09): For AI awareness of explodables
trigs = GetEntArray("explodable_volume", "targetname");
array_thread(trigs, ::explodable_volume);

level.ai_number = 0;
level.shared_portable_turrets = [];

// Call the spawner main and then the spawn manager main
maps\_spawner::main();
maps\_spawn_manager::spawn_manager_main();

maps\_hud::init();

thread maps\_animatedmodels::main();
script_gen_dump();
thread weapon_ammo();

PrecacheShellShock( "default" );

level thread maps\_gameskill::aa_init_stats();

level thread onFirstPlayerReady();
level thread onPlayerConnect();

maps\_swimming::main();

// Handles the "placed weapons" in the map. Deletes the ones that we do not want depending on the amount of coop players
level thread adjust_placed_weapons();


// Fog in splitscreen
if( IsSplitScreen() )
{
set_splitscreen_fog( 350, 2986.33, 10000, -480, 0.805, 0.715, 0.61, 0.0, 10000 );
}

level notify( "load main complete" );

/#
debug_replay( "File: _zombiemode_load.gsc. Function: main() - COMPLETE\n" );
#/

/#
level thread level_notify_listener();
level thread client_notify_listener();
level thread save_game_on_notify();
#/

println( "_LOAD END TIME = " + GetTime() );
}

onPlayerConnect()
{
for( ;; )
{
level waittill( "connecting", player );

// do not redefine the .a variable if there already is one
if( !IsDefined( player.a ) )
{
player.a = SpawnStruct();
}

player thread animscripts\zombie_init::onPlayerConnect();
player thread onPlayerSpawned();
player thread onPlayerDisconnect();

// if we are in splitscreen then turn the water off to
// help the frame rate
if( IsSplitScreen() )
{
SetDvar( "r_watersim", false );
}
}
}

onPlayerDisconnect()
{
self waittill( "disconnect" );

// if we are in dropping out of splitscreen then turn
// the water back on
if( IsSplitScreen() )
{
SetDvar( "r_watersim", true );
}
}

// CODE_MOD
// moved most of the player initialization functionality out of the main() function
// into player_init() so we can call it every spawn. Nothing should be in here
// that you dont want to happen every spawn.
onPlayerSpawned()
{
/#
debug_replay( "File: _zombiemode_load.gsc. Function: onPlayerSpawned()\n" );
#/

self endon( "disconnect" );

// TODO CAC ?? Will need this if special grenades and bettys are brought over to sp/coop
//self thread onPlayerSpawnedWeapons();

for( ;; )
{
/#
debug_replay( "File: _zombiemode_load.gsc. Function: onPlayerSpawned() - INNER LOOP START\n" );

debug_replay( "File: _zombiemode_load.gsc. Function: onPlayerSpawned() - INNER LOOP START WAIT\n" );
#/

self GiveWeapon( "m1911_zm" );
self SetSpawnWeapon( "m1911_zm" );

self waittill( "spawned_player" );

/#
debug_replay( "File: _zombiemode_load.gsc. Function: onPlayerSpawned() - 3\n" );
#/

if( level.mutators[ "mutator_susceptible" ] )
{
self.maxhealth = 50;
self.health = 50;
}
else
{
self.maxhealth = 100;
}
self.attackeraccuracy = 1;

self.pers["class"] = "closequarters";
self.pers["team"] = "allies";

println( "player health: "+self.health );

// MikeD: Stop all of the extra stuff, if createFX is enabled.
if( level.createFX_enabled )
{
continue;
}

/#
debug_replay( "File: _zombiemode_load.gsc. Function: onPlayerSpawned() - 4\n" );
#/

self SetThreatBiasGroup( "allies" );

self notify( "noHealthOverlay" );

// SCRIPTER_MOD: JesseS( 6/4/200 ): added start health for co-op health scaling
self.starthealth = self.maxhealth;

self.shellshocked = false;
self.inWater = false;

// make sure any existing attachments have been removed
self DetachAll();

players = get_players();
if( players.size == 1 && (1 != GetDvarInt( #"zombiefive_norandomchar" )) ) // ww: randomize the character a solo player has
{
self.zm_random_char = RandomInt( 4 );
self maps\_loadout::give_model( self.zm_random_char );
}
else
{
self maps\_loadout::give_model( self.pers["class"] );
}


// TODO CAC remove default loadout
maps\_loadout::give_loadout( true );

self notify ( "CAC_loadout");
// SCRIPTER_MOD: SRS 5/3/2008: to support _weather
/* if( IsDefined( level.playerWeatherStarted ) && level.playerWeatherStarted )
{
self thread maps\_weather::player_weather_loop();
} */

// ww: set viewmodel based on character
if ( !isDefined(level.zombietron_mode) )
{
players = get_players();
if( players.size == 1 && IsDefined( self.zm_random_char ) )
{
self player_set_viewmodel( self.zm_random_char );
}
self player_set_viewmodel();
}

self maps\_art::setdefaultdepthoffield();

if( !IsDefined( self.player_inited ) || !self.player_inited )
{
self maps\_friendlyfire::player_init();

// CODER_MOD - JamesS added self to player_death_detection
self thread player_death_detection();
// self thread flashMonitor();
self thread shock_ondeath();
self thread shock_onpain();

// handles satchels/claymores with special script
self thread maps\_detonategrenades::watchGrenadeUsage();
self maps\_dds::player_init();

self thread playerDamageRumble();
self thread maps\_gameskill::playerHealthRegen();
self thread maps\_colors::player_init_color_grouping();

self maps\_laststand::revive_hud_create();

self thread maps\_cheat::player_init();

wait( 0.05 );
self.player_inited = true;
}
/#
debug_replay( "File: _zombiemode_load.gsc. Function: onPlayerSpawned() - 5\n" );
#/
}
}


// ww: set the viewmodel arms based on the client number
// SELF == PLAYER
player_set_viewmodel( zm_random_solo_char )
{
// WWilliams (8/18/10) Randomize what character is used in Solo play
if( IsDefined( zm_random_solo_char ) )
{
self.entity_num = zm_random_solo_char;
}

// WWilliams (8/11/10) Used to determine if it is player 1, 2, 3, or 4, to give the appropriate model.
if( !IsDefined( self.entity_num ) )
{
self.entity_num = self GetEntityNumber();
}

if( IsSubStr( level.script, "zombie_theater" ) ) // WWilliams (8/11/10) Only set these if the level is theater
{
switch( self.entity_num ) // These models are precached in zombie_theater.gsc and stored in zombie_theater.csv
{
case 0:
// Dempsey
self SetViewModel( "viewmodel_usa_pow_arms" );
break;
case 1:
// Nikolai
self SetViewModel( "viewmodel_rus_prisoner_arms" );
break;
case 2:
// Takeo
self SetViewModel( "viewmodel_vtn_nva_standard_arms" );
break;
case 3:
// Richtofen
self SetViewModel( "viewmodel_usa_hazmat_arms" );
break;
}
}
else if( IsSubStr( level.script, "zombie_pentagon" ) )
{
switch( self.entity_num )
{
case 0:
// JFK
self SetViewModel( "viewmodel_usa_pow_arms" );
break;

case 1:
// Mcnamara
self SetViewModel( "viewmodel_usa_pow_arms" );
break;

case 2:
// Nixon
self SetViewModel( "viewmodel_usa_pow_arms" );
break;

case 3:
// Castro
self SetViewModel( "viewmodel_usa_pow_arms" );
break;
}
}
else
{
// default
self SetViewModel( "viewmodel_usa_pow_arms" );
}
}
Zombiemode_money
#include maps\_utility;
#include common_scripts\utility;
#include maps\_zombiemode_utility;
#include animscripts\zombie_Utility;

//-----------------------------------------------------------------------------------
// setup for money dropping
//-----------------------------------------------------------------------------------
init()
{
thread check_players();

level.money_dump_delay = 500;
level.money_dump_size = 500;
}

//-----------------------------------------------------------------------------------
// precache models, materials, etc
//-----------------------------------------------------------------------------------
money_precache()
{
PrecacheModel( "zombie_z_money_icon" );
}

//-----------------------------------------------------------------------------------
// setup for each player
//-----------------------------------------------------------------------------------
check_players()
{
flag_wait( "all_players_connected" );

players = getplayers();
for ( i = 0; i {
if ( players.size > 1 )
{
players[i] thread money_dump();
}
}
}

//-----------------------------------------------------------------------------------
// check if player is allowed to dump
//-----------------------------------------------------------------------------------
player_can_dump()
{
if ( self.score {
return false;
}

if ( self.sessionstate == "spectator" )
{
return false;
}

if ( self maps\_laststand::player_is_in_laststand() )
{
return false;
}

if ( isdefined( self.lander ) && self.lander == true )
{
return false;
}

return true;
}

//-----------------------------------------------------------------------------------
// check dpad for player to dump
//-----------------------------------------------------------------------------------
money_dump()
{
self endon( "disconnect" );

self.moneyDump = undefined;

while ( 1 )
{
if ( self player_can_dump() )
{
while ( self actionslottwobuttonpressed() )
{
// drop some money
if ( !isDefined( self.moneyDump ) )
{
self.moneyDump = thread money_spawn( self );
}

if ( self.score >= level.money_dump_size )
{
self.old_score -= level.money_dump_size;
self.score -= level.money_dump_size;

self.moneyDump.score += level.money_dump_size;
}

wait( 0.05 );
}
}

wait( 0.05 );
}
}

//-----------------------------------------------------------------------------------
// put money icon in the level
//-----------------------------------------------------------------------------------
money_spawn( player )
{
money = spawn( "script_model", player.origin + ( 0, 0, 40 ) );
money.angles = player.angles;

money SetModel( "zombie_z_money_icon" );
money.score = 0;
money.player = player;

money thread money_wobble();
money thread money_grab();

return money;
}

//-----------------------------------------------------------------------------------
// wait for player to get money
//-----------------------------------------------------------------------------------
money_grab()
{
while ( isdefined( self ) )
{
players = get_players();

for ( i = 0; i {
if ( players[i].is_zombie )
{
continue;
}

if ( players[i] == self.player )
{
continue;
}

dist = distance( players[i].origin, self.origin );
if ( dist {
playfx( level._effect["powerup_grabbed"], self.origin );
playfx( level._effect["powerup_grabbed_wave"], self.origin );
playsoundatposition("zmb_powerup_grabbed_3p", self.origin);

players[i].old_score += self.score;
players[i].score += self.score;

wait( 0.1 );

playsoundatposition("zmb_cha_ching", self.origin);
self stoploopsound();

self.player.moneyDump = undefined;

self delete();
self notify( "money_grabbed" );
break;
}
}

wait_network_frame();
}
}

//-----------------------------------------------------------------------------------
// bounce the money around
//-----------------------------------------------------------------------------------
money_wobble()
{
self endon ("money_grabbed");

if (isdefined(self))
{
playfxontag (level._effect["powerup_on"], self, "tag_origin");
self playsound("zmb_spawn_powerup");
self playloopsound("zmb_spawn_powerup_loop");
}

while (isdefined(self))
{
self rotateyaw( 360, 3, 3, 0 );
self waittill("rotatedone");
//
}
}

Zombiemode_net
#include maps\_utility; 

network_choke_init( id, max )
{
if ( !IsDefined( level.zombie_network_choke_ids_max ) )
{
level.zombie_network_choke_ids_max = [];
level.zombie_network_choke_ids_count = [];
}

level.zombie_network_choke_ids_max[ id ] = max;
level.zombie_network_choke_ids_count[ id ] = 0;

level thread network_choke_thread( id );
}


network_choke_thread( id )
{
while( 1 )
{
wait_network_frame();
wait_network_frame();
level.zombie_network_choke_ids_count[ id ] = 0;
}
}


network_choke_safe( id )
{
return( level.zombie_network_choke_ids_count[ id ] }


network_choke_action( id, choke_action, arg1, arg2, arg3 )
{
AssertEx( IsDefined( level.zombie_network_choke_ids_max[ id ] ), "Network Choke: " + id + " undefined" );

while( !network_choke_safe( id ) )
{
wait( 0.05 );
}

level.zombie_network_choke_ids_count[ id ]++;

if ( !IsDefined( arg1 ) )
{
return ( [[choke_action]]() );
}

if ( !IsDefined( arg2 ) )
{
return ( [[choke_action]]( arg1 ) );
}

if ( !IsDefined( arg3 ) )
{
return ( [[choke_action]]( arg1, arg2 ) );
}

return ( [[choke_action]]( arg1, arg2, arg3 ) );
}


network_entity_valid( entity )
{
if( !IsDefined( entity ) )
{
return false;
}

return true;
}


network_safe_init( id, max )
{
if ( !IsDefined( level.zombie_network_choke_ids_max ) || !IsDefined( level.zombie_network_choke_ids_max[ id ] ) )
{
network_choke_init( id, max );
}

assert( max == level.zombie_network_choke_ids_max[ id ] );
}


// SPAWNING
_network_safe_spawn( classname, origin )
{
return Spawn( classname, origin );
}


network_safe_spawn( id, max, classname, origin )
{
network_safe_init( id, max );
return ( network_choke_action( id, ::_network_safe_spawn, classname, origin ) );
}


// FX
_network_safe_play_fx_on_tag( fx, entity, tag )
{
if ( network_entity_valid( entity ) )
{
PlayFxOnTag( fx, entity, tag );
}
}


network_safe_play_fx_on_tag( id, max, fx, entity, tag )
{
network_safe_init( id, max );
network_choke_action( id, ::_network_safe_play_fx_on_tag, fx, entity, tag );
}

_network_safe_stalingrad_spawn( spawner )
{
return spawner stalingradspawn();
}

network_safe_stalingrad_spawn( id, max )
{
network_safe_init( id, max );
return( network_choke_action( id, ::_network_safe_stalingrad_spawn, self ) );
}

Link to comment

Zombiemode_perks

#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;

init()
{
// Perks-a-cola vending machine use triggers
vending_triggers = GetEntArray( "zombie_vending", "targetname" );

// Pack-A-Punch weapon upgrade machine use triggers
vending_weapon_upgrade_trigger = GetEntArray("zombie_vending_upgrade", "targetname");
flag_init("pack_machine_in_use");
flag_init( "solo_game" );

if( level.mutators["mutator_noPerks"] )
{
for( i = 0; i {
vending_triggers[i] disable_trigger();
}
for( i = 0; i {
vending_weapon_upgrade_trigger[i] disable_trigger();
}
return;
}

if ( vending_triggers.size {
return;
}

if ( vending_weapon_upgrade_trigger.size >= 1 )
{
array_thread( vending_weapon_upgrade_trigger, ::vending_weapon_upgrade );;
}

//Perks machine
if( !isDefined( level.custom_vending_precaching ) )
{
level.custom_vending_precaching = maps\_zombiemode_perks::default_vending_precaching;
}
[[ level.custom_vending_precaching ]]();

if( !isDefined( level.packapunch_timeout ) )
{
level.packapunch_timeout = 15;
}

set_zombie_var( "zombie_perk_cost", 2000 );
if( level.mutators["mutator_susceptible"] )
{
set_zombie_var( "zombie_perk_juggernaut_health", 80 );
set_zombie_var( "zombie_perk_juggernaut_health_upgrade", 95 );
}
else
{
set_zombie_var( "zombie_perk_juggernaut_health", 160 );
set_zombie_var( "zombie_perk_juggernaut_health_upgrade", 190 );
}

array_thread( vending_triggers, ::vending_trigger_think );
array_thread( vending_triggers, ::electric_perks_dialog );

level thread turn_doubletap_on();
level thread turn_jugger_on();
level thread turn_revive_on();
level thread turn_sleight_on();

level thread turn_PackAPunch_on();
}


//
// Precaches all machines
//
// "weapon" - 1st person Bottle when drinking
// icon - Texture for when perk is active
// model - Perk Machine on/off versions
// fx - machine on
// sound
default_vending_precaching()
{
PrecacheItem( "zombie_perk_bottle_doubletap" );
PrecacheItem( "zombie_perk_bottle_jugg" );
PrecacheItem( "zombie_perk_bottle_revive" );
PrecacheItem( "zombie_perk_bottle_sleight" );
PrecacheItem( "zombie_knuckle_crack" );

PrecacheShader( "specialty_doubletap_zombies" );
PrecacheShader( "specialty_juggernaut_zombies" );
PrecacheShader( "specialty_quickrevive_zombies" );
PrecacheShader( "specialty_fastreload_zombies" );
PrecacheShader( "specialty_juggernaut_zombies_pro" );
PrecacheShader( "specialty_quickrevive_zombies_pro" );
PrecacheShader( "specialty_fastreload_zombies_pro" );

// Minimap icons
PrecacheShader( "minimap_icon_juggernog" );
PrecacheShader( "minimap_icon_revive" );
PrecacheShader( "minimap_icon_reload" );

PrecacheModel("zombie_vending_doubletap_on");
PrecacheModel("zombie_vending_jugg_on");
PrecacheModel("zombie_vending_revive_on");
PrecacheModel("zombie_vending_sleight_on");
PrecacheModel("zombie_vending_packapunch_on");

PrecacheString( &"ZOMBIE_PERK_DOUBLETAP" );
PrecacheString( &"ZOMBIE_PERK_JUGGERNAUT" );
PrecacheString( &"ZOMBIE_PERK_QUICKREVIVE" );
PrecacheString( &"ZOMBIE_PERK_FASTRELOAD" );
PrecacheString( &"ZOMBIE_PERK_PACKAPUNCH" );

level._effect["doubletap_light"] = loadfx("misc/fx_zombie_cola_dtap_on");
level._effect["jugger_light"] = loadfx("misc/fx_zombie_cola_jugg_on");
level._effect["revive_light"] = loadfx("misc/fx_zombie_cola_revive_on");
level._effect["sleight_light"] = loadfx("misc/fx_zombie_cola_on");

level._effect["packapunch_fx"] = loadfx("maps/zombie/fx_zombie_packapunch");

// solo revive flicker
level._effect["revive_light_flicker"] = loadfx("misc/fx_zombie_cola_revive_flicker");
}

third_person_weapon_upgrade( current_weapon, origin, angles, packa_rollers, perk_machine )
{
forward = anglesToForward( angles );
interact_pos = origin + (forward*-25);
PlayFx( level._effect["packapunch_fx"], origin+(0,1,-34), forward );

worldgun = spawn( "script_model", interact_pos );
worldgun.angles = self.angles;
worldgun setModel( GetWeaponModel( current_weapon ) );
worldgun useweaponhidetags( current_weapon );
worldgun rotateto( angles+(0,90,0), 0.35, 0, 0 );

offsetdw = ( 3, 3, 3 );
worldgundw = undefined;
if ( maps\_zombiemode_weapons::weapon_is_dual_wield( current_weapon ) )
{
worldgundw = spawn( "script_model", interact_pos + offsetdw );
worldgundw.angles = self.angles;
worldgundw setModel( GetWeaponModel( current_weapon ) );
worldgundw useweaponhidetags( current_weapon );
worldgundw rotateto( angles+(0,90,0), 0.35, 0, 0 );
}

wait( 0.5 );

worldgun moveto( origin, 0.5, 0, 0 );
if ( isdefined( worldgundw ) )
{
worldgundw moveto( origin + offsetdw, 0.5, 0, 0 );
}

packa_rollers playsound( "zmb_perks_packa_upgrade" );
if( isDefined( perk_machine.wait_flag ) )
{
perk_machine.wait_flag rotateto( perk_machine.wait_flag.angles+(179, 0, 0), 0.25, 0, 0 );
}
wait( 0.35 );

worldgun delete();
if ( isdefined( worldgundw ) )
{
worldgundw delete();
}

wait( 3 );

packa_rollers playsound( "zmb_perks_packa_ready" );

worldgun = spawn( "script_model", origin );
worldgun.angles = angles+(0,90,0);
worldgun setModel( GetWeaponModel( level.zombie_weapons[current_weapon].upgrade_name ) );
worldgun useweaponhidetags( level.zombie_weapons[current_weapon].upgrade_name );
worldgun moveto( interact_pos, 0.5, 0, 0 );

worldgundw = undefined;
if ( maps\_zombiemode_weapons::weapon_is_dual_wield( level.zombie_weapons[current_weapon].upgrade_name ) )
{
worldgundw = spawn( "script_model", origin + offsetdw );
worldgundw.angles = angles+(0,90,0);
worldgundw setModel( GetWeaponModel( level.zombie_weapons[current_weapon].upgrade_name ) );
worldgundw useweaponhidetags( level.zombie_weapons[current_weapon].upgrade_name );
worldgundw moveto( interact_pos + offsetdw, 0.5, 0, 0 );
}

if( isDefined( perk_machine.wait_flag ) )
{
perk_machine.wait_flag rotateto( perk_machine.wait_flag.angles-(179, 0, 0), 0.25, 0, 0 );
}

wait( 0.5 );

worldgun moveto( origin, level.packapunch_timeout, 0, 0);
if ( isdefined( worldgundw ) )
{
worldgundw moveto( origin + offsetdw, level.packapunch_timeout, 0, 0);
}

worldgun.worldgundw = worldgundw;
return worldgun;
}


//
// Pack-A-Punch Weapon Upgrade
//
vending_weapon_upgrade()
{
perk_machine = GetEnt( self.target, "targetname" );
perk_machine_sound = GetEntarray ( "perksacola", "targetname");

if( isDefined( perk_machine.target ) )
{
perk_machine.wait_flag = GetEnt( perk_machine.target, "targetname" );
}

self UseTriggerRequireLookAt();
self SetHintString( &"ZOMBIE_NEED_POWER" );
self SetCursorHint( "HINT_NOICON" );
level waittill("Pack_A_Punch_on");

self thread maps\_zombiemode_weapons::decide_hide_show_hint();

packa_rollers = spawn("script_origin", self.origin);
packa_timer = spawn("script_origin", self.origin);
packa_rollers playloopsound("zmb_perks_packa_loop");

self thread vending_weapon_upgrade_cost();

for( ;; )
{
self waittill( "trigger", player );
flag_set("pack_machine_in_use");

index = maps\_zombiemode_weapons::get_player_index(player);
plr = "zmb_vox_plr_" + index + "_";
current_weapon = player getCurrentWeapon();

if( !player maps\_zombiemode_weapons::can_buy_weapon() ||
player maps\_laststand::player_is_in_laststand() ||
is_true( player.intermission ) ||
player isThrowingGrenade() ||
player maps\_zombiemode_weapons::is_weapon_upgraded( current_weapon ) )
{
wait( 0.1 );
continue;
}

//Z2 - UPDATED Missing script API call : isSwitchingWeapons()
// if( player isSwitchingWeapons() )
// {
// wait(0.1);
// continue;
// }

if ( !IsDefined( level.zombie_include_weapons[current_weapon] ) )
{
continue;
}

if ( player.score {
//player iprintln( "Not enough points to buy Perk: " + perk );
self playsound("deny");
player maps\_zombiemode_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 );
continue;
}
player maps\_zombiemode_score::minus_to_player_score( self.cost );
sound = "evt_bottle_dispense";
playsoundatposition(sound, self.origin);

//TUEY TODO: Move this to a general init string for perk audio later on
self thread maps\_zombiemode_audio::play_jingle_or_stinger("mus_perks_packa_sting");
player maps\_zombiemode_audio::create_and_play_dialog( "weapon_pickup", "upgrade_wait" );

origin = self.origin;
angles = self.angles;

if( isDefined(perk_machine))
{
origin = perk_machine.origin+(0,0,35);
angles = perk_machine.angles+(0,90,0);
}

self disable_trigger();

player thread do_knuckle_crack();

// Remember what weapon we have. This is needed to check unique weapon counts.
self.current_weapon = current_weapon;

weaponmodel = player third_person_weapon_upgrade( current_weapon, origin, angles, packa_rollers, perk_machine );

self enable_trigger();
self SetHintString( &"ZOMBIE_GET_UPGRADED" );
self setvisibletoplayer( player );

self thread wait_for_player_to_take( player, current_weapon, packa_timer );
self thread wait_for_timeout( packa_timer );

self waittill_either( "pap_timeout", "pap_taken" );

self.current_weapon = "";
if ( isdefined( weaponmodel.worldgundw ) )
{
weaponmodel.worldgundw delete();
}
weaponmodel delete();
self SetHintString( &"ZOMBIE_PERK_PACKAPUNCH", self.cost );
self setvisibletoall();
flag_clear("pack_machine_in_use");

}
}


vending_weapon_upgrade_cost()
{
while ( 1 )
{
self.cost = 5000;
self SetHintString( &"ZOMBIE_PERK_PACKAPUNCH", self.cost );

level waittill( "powerup bonfire sale" );

self.cost = 1000;
self SetHintString( &"ZOMBIE_PERK_PACKAPUNCH", self.cost );

level waittill( "bonfire_sale_off" );
}
}


//
//
wait_for_player_to_take( player, weapon, packa_timer )
{
AssertEx( IsDefined( level.zombie_weapons[weapon] ), "wait_for_player_to_take: weapon does not exist" );
AssertEx( IsDefined( level.zombie_weapons[weapon].upgrade_name ), "wait_for_player_to_take: upgrade_weapon does not exist" );

upgrade_weapon = level.zombie_weapons[weapon].upgrade_name;

self endon( "pap_timeout" );
while( true )
{
packa_timer playloopsound( "zmb_perks_packa_ticktock" );
self waittill( "trigger", trigger_player );
packa_timer stoploopsound(.05);
if( trigger_player == player )
{
if( !player maps\_laststand::player_is_in_laststand() && !is_true( player.intermission ) )
{
self notify( "pap_taken" );
primaries = player GetWeaponsListPrimaries();
if( isDefined( primaries ) && primaries.size >= 2 )
{
player maps\_zombiemode_weapons::weapon_give( upgrade_weapon );
}
else
{
player GiveWeapon( upgrade_weapon, 0, player maps\_zombiemode_weapons::get_pack_a_punch_weapon_options( upgrade_weapon ) );
player GiveStartAmmo( upgrade_weapon );
}

player SwitchToWeapon( upgrade_weapon );
player maps\_zombiemode_weapons::play_weapon_vo(upgrade_weapon);
return;
}
}
wait( 0.05 );
}
}


// Waiting for the weapon to be taken
//
wait_for_timeout( packa_timer )
{
self endon( "pap_taken" );

wait( level.packapunch_timeout );

self notify( "pap_timeout" );
packa_timer stoploopsound(.05);
packa_timer playsound( "zmb_perks_packa_deny" );
}


// Weapon has been inserted, crack knuckles while waiting
//
do_knuckle_crack()
{
gun = self upgrade_knuckle_crack_begin();

self waittill_any( "fake_death", "death", "player_downed", "weapon_change_complete" );

self upgrade_knuckle_crack_end( gun );

}


// Switch to the knuckles
//
upgrade_knuckle_crack_begin()
{
self increment_is_drinking();

self AllowLean( false );
self AllowAds( false );
self AllowSprint( false );
self AllowCrouch( true );
self AllowProne( false );
self AllowMelee( false );

if ( self GetStance() == "prone" )
{
self SetStance( "crouch" );
}

primaries = self GetWeaponsListPrimaries();

gun = self GetCurrentWeapon();
weapon = "zombie_knuckle_crack";

if ( gun != "none" && gun != "mine_bouncing_betty" && gun != "claymore_zm" )
{
self notify( "zmb_lost_knife" );
self TakeWeapon( gun );
}
else
{
return;
}

self GiveWeapon( weapon );
self SwitchToWeapon( weapon );

return gun;
}

// Anim has ended, now switch back to something
//
upgrade_knuckle_crack_end( gun )
{
assert( gun != "zombie_perk_bottle_doubletap" );
assert( gun != "zombie_perk_bottle_jugg" );
assert( gun != "zombie_perk_bottle_revive" );
assert( gun != "zombie_perk_bottle_sleight" );
assert( gun != "syrette_sp" );

self AllowLean( true );
self AllowAds( true );
self AllowSprint( true );
self AllowProne( true );
self AllowMelee( true );
weapon = "zombie_knuckle_crack";

// TODO: race condition?
if ( self maps\_laststand::player_is_in_laststand() || is_true( self.intermission ) )
{
self TakeWeapon(weapon);
return;
}

self decrement_is_drinking();

self TakeWeapon(weapon);
primaries = self GetWeaponsListPrimaries();
if( self is_drinking() )
{
return;
}
else if( isDefined( primaries ) && primaries.size > 0 )
{
self SwitchToWeapon( primaries[0] );
}
else
{
self SwitchToWeapon( level.laststandpistol );
}
}

// PI_CHANGE_BEGIN
// NOTE: In the .map, you'll have to make sure that each Pack-A-Punch machine has a unique targetname
turn_PackAPunch_on()
{
level waittill("Pack_A_Punch_on");

vending_weapon_upgrade_trigger = GetEntArray("zombie_vending_upgrade", "targetname");
for(i=0; i {
perk = getent(vending_weapon_upgrade_trigger[i].target, "targetname");
if(isDefined(perk))
{
perk thread activate_PackAPunch();
}
}
}

activate_PackAPunch()
{
self setmodel("zombie_vending_packapunch_on");
self playsound("zmb_perks_power_on");
self vibrate((0,-100,0), 0.3, 0.4, 3);
/*
self.flag = spawn( "script_model", machine GetTagOrigin( "tag_flag" ) );
self.angles = machine GetTagAngles( "tag_flag" );
self.flag setModel( "zombie_sign_please_wait" );
self.flag linkto( machine );
self.flag.origin = (0, 40, 40);
self.flag.angles = (0, 0, 0);
*/
timer = 0;
duration = 0.05;

level notify( "Carpenter_On" );
}
// PI_CHANGE_END



//############################################################################
// P E R K M A C H I N E S
//############################################################################

//
// Threads to turn the machines to their ON state.
//


// Speed Cola / Sleight of Hand
//
turn_sleight_on()
{
machine = getentarray("vending_sleight", "targetname");

level waittill("sleight_on");

for( i = 0; i {
machine[i] setmodel("zombie_vending_sleight_on");
machine[i] vibrate((0,-100,0), 0.3, 0.4, 3);
machine[i] playsound("zmb_perks_power_on");
machine[i] thread perk_fx( "sleight_light" );
}

level notify( "specialty_fastreload_power_on" );
}

// Quick Revive
//
turn_revive_on()
{
machine = getentarray("vending_revive", "targetname");
machine_model = undefined;
machine_clip = undefined;

flag_wait( "all_players_connected" );
players = GetPlayers();
if ( players.size == 1 )
{
for( i = 0; i {
if(IsDefined(machine[i].script_noteworthy) && machine[i].script_noteworthy == "clip")
{
machine_clip = machine[i];
}
else // then the model
{
machine[i] setmodel("zombie_vending_revive_on");
machine_model = machine[i];
}
}
wait_network_frame();
machine_model thread revive_solo_fx(machine_clip);
}
else
{
level waittill("revive_on");

for( i = 0; i {
if(IsDefined(machine[i].classname) && machine[i].classname == "script_model")
{
machine[i] setmodel("zombie_vending_revive_on");
machine[i] playsound("zmb_perks_power_on");
machine[i] vibrate((0,-100,0), 0.3, 0.4, 3);
machine[i] thread perk_fx( "revive_light" );
}
}

level notify( "specialty_quickrevive_power_on" );
}
}


revive_solo_fx(machine_clip)
{
flag_init( "solo_revive" );

self.fx = Spawn( "script_model", self.origin );
self.fx.angles = self.angles;
self.fx SetModel( "tag_origin" );
self.fx LinkTo(self);

playfxontag( level._effect[ "revive_light" ], self.fx, "tag_origin" );
playfxontag( level._effect[ "revive_light_flicker" ], self.fx, "tag_origin" );

flag_wait( "solo_revive" );

//DCS: make revive model fly away like a magic box.
//self playsound("zmb_laugh_child");

wait(2.0);

self playsound("zmb_box_move");

playsoundatposition ("zmb_whoosh", self.origin );
//playsoundatposition ("zmb_vox_ann_magicbox", self.origin );

self moveto(self.origin + (0,0,40),3);

if( isDefined( level.custom_vibrate_func ) )
{
[[ level.custom_vibrate_func ]]( self );
}
else
{
direction = self.origin;
direction = (direction[1], direction[0], 0);

if(direction[1] 0 && direction[1] > 0))
{
direction = (direction[0], direction[1] * -1, 0);
}
else if(direction[0] {
direction = (direction[0] * -1, direction[1], 0);
}

self Vibrate( direction, 10, 0.5, 5);
}

self waittill("movedone");
PlayFX(level._effect["poltergeist"], self.origin);
playsoundatposition ("zmb_box_poof", self.origin);

//self setmodel("zombie_vending_revive");
self.fx Unlink();
self.fx delete();
self Delete();

// DCS: remove the clip.
machine_clip MoveZ(-200,0.1 );
machine_clip waittill("movedone");
machine_clip ConnectPaths();
machine_clip Delete();

}

// Jugger-nog / Juggernaut
//
turn_jugger_on()
{
machine = getentarray("vending_jugg", "targetname");

level waittill("juggernog_on");

for( i = 0; i {
machine[i] setmodel("zombie_vending_jugg_on");
machine[i] vibrate((0,-100,0), 0.3, 0.4, 3);
machine[i] playsound("zmb_perks_power_on");
machine[i] thread perk_fx( "jugger_light" );
}
level notify( "specialty_armorvest_power_on" );

}

// Double-Tap
//
turn_doubletap_on()
{
machine = getentarray("vending_doubletap", "targetname");
level waittill("doubletap_on");

for( i = 0; i {
machine[i] setmodel("zombie_vending_doubletap_on");
machine[i] vibrate((0,-100,0), 0.3, 0.4, 3);
machine[i] playsound("zmb_perks_power_on");
machine[i] thread perk_fx( "doubletap_light" );
}
level notify( "specialty_rof_power_on" );
level notify( "specialty_threeprimaries_power_on" );
}

//
//
perk_fx( fx )
{
wait(3);
playfxontag( level._effect[ fx ], self, "tag_origin" );
}




electric_perks_dialog()
{
//TODO TEMP Disable Revive in Solo games
flag_wait( "all_players_connected" );
players = GetPlayers();
if ( players.size == 1 )
{
return;
}

self endon ("warning_dialog");
level endon("switch_flipped");
timer =0;
while(1)
{
wait(0.5);
players = get_players();
for(i = 0; i {
dist = distancesquared(players[i].origin, self.origin );
if(dist > 70*70)
{
timer = 0;
continue;
}
if(dist {
wait(0.5);
timer ++;
}
if(dist {

players[i] thread do_player_vo("vox_start", 5);
wait(3);
self notify ("warning_dialog");
/#
iprintlnbold("warning_given");
#/
}
}
}
}


//
//
vending_trigger_think()
{
//self thread turn_cola_off();
perk = self.script_noteworthy;
solo = false;
flag_init( "_start_zm_pistol_rank" );

//TODO TEMP Disable Revive in Solo games
if ( IsDefined(perk) &&
(perk == "specialty_quickrevive" || perk == "specialty_quickrevive_upgrade") )
{
flag_wait( "all_players_connected" );
players = GetPlayers();
if ( players.size == 1 )
{
solo = true;
flag_set( "solo_game" );
level.solo_lives_given = 0;
players[0].lives = 0;
level maps\_zombiemode::zombiemode_solo_last_stand_pistol();
}
}

flag_set( "_start_zm_pistol_rank" );

if ( !solo )
{
self SetHintString( &"ZOMBIE_NEED_POWER" );
}

self SetCursorHint( "HINT_NOICON" );
self UseTriggerRequireLookAt();

if ( !solo )
{
notify_name = perk + "_power_on";
level waittill( notify_name );
}

if(!IsDefined(level._perkmachinenetworkchoke))
{
level._perkmachinenetworkchoke = 0;
}
else
{
level._perkmachinenetworkchoke ++;
}

for(i = 0; i {
wait_network_frame();
}

//Turn on music timer
self thread maps\_zombiemode_audio::perks_a_cola_jingle_timer();

perk_hum = spawn("script_origin", self.origin);
perk_hum playloopsound("zmb_perks_machine_loop");

self thread check_player_has_perk(perk);

cost = level.zombie_vars["zombie_perk_cost"];
switch( perk )
{
case "specialty_armorvest_upgrade":
case "specialty_armorvest":
cost = 2500;
self SetHintString( &"ZOMBIE_PERK_JUGGERNAUT", cost );
break;

case "specialty_quickrevive_upgrade":
case "specialty_quickrevive":
if( solo )
{
cost = 500;
self SetHintString( &"ZOMBIE_PERK_QUICKREVIVE_SOLO", cost );
}
else
{
cost = 1500;
self SetHintString( &"ZOMBIE_PERK_QUICKREVIVE", cost );
}
break;

case "specialty_fastreload_upgrade":
case "specialty_fastreload":
cost = 3000;
self SetHintString( &"ZOMBIE_PERK_FASTRELOAD", cost );
break;

case "specialty_rof_upgrade":
case "specialty_rof":
cost = 2000;
self SetHintString( &"ZOMBIE_PERK_DOUBLETAP", cost );
break;

default:
self SetHintString( perk + " Cost: " + level.zombie_vars["zombie_perk_cost"] );
}

for( ;; )
{
self waittill( "trigger", player );

index = maps\_zombiemode_weapons::get_player_index(player);

if (player maps\_laststand::player_is_in_laststand() || is_true( player.intermission ) )
{
continue;
}

if(player in_revive_trigger())
{
continue;
}

if( player isThrowingGrenade() )
{
wait( 0.1 );
continue;
}

//Z2 - UPDATED Missing script API call : isSwitchingWeapons()
// if( player isSwitchingWeapons() )
// {
// wait(0.1);
// continue;
// }

if( player is_drinking() )
{
wait( 0.1 );
continue;
}

if ( player HasPerk( perk ) )
{
cheat = false;

/#
if ( GetDvarInt( #"zombie_cheat" ) >= 5 )
{
cheat = true;
}
#/

if ( cheat != true )
{
//player iprintln( "Already using Perk: " + perk );
self playsound("deny");
player maps\_zombiemode_audio::create_and_play_dialog( "general", "perk_deny", undefined, 1 );


continue;
}
}

if ( player.score {
//player iprintln( "Not enough points to buy Perk: " + perk );
self playsound("evt_perk_deny");
player maps\_zombiemode_audio::create_and_play_dialog( "general", "perk_deny", undefined, 0 );
continue;
}

sound = "evt_bottle_dispense";
playsoundatposition(sound, self.origin);
player maps\_zombiemode_score::minus_to_player_score( cost );

//if( player unlocked_perk_upgrade( perk ) )
//{
// perk += "_upgrade";
//}

///bottle_dispense
switch( perk )
{
case "specialty_armorvest_upgrade":
case "specialty_armorvest":
sound = "mus_perks_jugger_sting";
break;

case "specialty_quickrevive_upgrade":
case "specialty_quickrevive":
sound = "mus_perks_revive_sting";
break;

case "specialty_fastreload_upgrade":
case "specialty_fastreload":
sound = "mus_perks_speed_sting";
break;

case "specialty_rof_upgrade":
case "specialty_rof":
sound = "mus_perks_doubletap_sting";
break;

default:
sound = "mus_perks_jugger_sting";
break;
}

self thread maps\_zombiemode_audio::play_jingle_or_stinger (self.script_label);

// self waittill("sound_done");


// do the drink animation
gun = player perk_give_bottle_begin( perk );
player waittill_any( "fake_death", "death", "player_downed", "weapon_change_complete" );

// restore player controls and movement
player perk_give_bottle_end( gun, perk );

// TODO: race condition?
if ( player maps\_laststand::player_is_in_laststand() || is_true( player.intermission ) )
{
continue;
}

player SetPerk( perk );

//AUDIO: Ayers - Sending Perk Name over to audio common script to play VOX
player thread maps\_zombiemode_audio::perk_vox( perk );
player setblur( 4, 0.1 );
wait(0.1);
player setblur(0, 0.1);
//earthquake (0.4, 0.2, self.origin, 100);
if(perk == "specialty_armorvest")
{
player.preMaxHealth = player.maxhealth;
player SetMaxHealth( level.zombie_vars["zombie_perk_juggernaut_health"] );
}
else if(perk == "specialty_armorvest_upgrade")
{
player.preMaxHealth = player.maxhealth;
player SetMaxHealth( level.zombie_vars["zombie_perk_juggernaut_health_upgrade"] );
}

// quick revive in solo gives an extra life
if ( solo && perk == "specialty_quickrevive" )
{
player.lives = 1;

level.solo_lives_given++;

if( level.solo_lives_given >= 3 )
{
flag_set( "solo_revive" );
}

player thread solo_revive_buy_trigger_move( self );

// self disable_trigger();
}

player perk_hud_create( perk );

//stat tracking
player.stats["perks"]++;

//player iprintln( "Bought Perk: " + perk );
bbPrint( "zombie_uses: playername %s playerscore %d teamscore %d round %d cost %d name %s x %f y %f z %f type perk",
player.playername, player.score, level.team_pool[ player.team_num ].score, level.round_number, cost, perk, self.origin );

player thread perk_think( perk );

}
}

// ww: tracks the player's lives in solo, once a life is used then the revive trigger is moved back in to position
solo_revive_buy_trigger_move( revive_perk_trigger )
{
self endon( "death" );

revive_perk_trigger trigger_off();

if( level.solo_lives_given >= 3 )
{
return;
}

while( self.lives > 0 )
{
wait( 0.1 );
}

revive_perk_trigger trigger_on();
}

unlocked_perk_upgrade( perk )
{
ch_ref = string(tablelookup( "mp/challengeTable_zmPerk.csv", 12, perk, 7 ));
ch_max = int(tablelookup( "mp/challengeTable_zmPerk.csv", 12, perk, 4 ));
ch_progress = self getdstat( "challengeStats", ch_ref, "challengeProgress" );

if( ch_progress >= ch_max )
{
return true;
}
return false;
}

give_perk( perk )
{
if( level.mutators["mutator_noPerks"] )
{
return;
}
self SetPerk( perk );
self perk_hud_create( perk );
self.stats["perks"]++;
self thread perk_think( perk );
}

check_player_has_perk(perk)
{
/#
if ( GetDvarInt( #"zombie_cheat" ) >= 5 )
{
return;
}
#/

dist = 128 * 128;
while(true)
{
players = get_players();
for( i = 0; i {
if(DistanceSquared( players[i].origin, self.origin ) {
if(!players[i] hasperk(perk) && !(players[i] in_revive_trigger()))
{
self setinvisibletoplayer(players[i], false);
}
else
{
self SetInvisibleToPlayer(players[i], true);
}
}
}
wait(0.1);

}
}


vending_set_hintstring( perk )
{
switch( perk )
{
case "specialty_armorvest_upgrade":
case "specialty_armorvest":
break;

}
}


perk_think( perk )
{
/#
if ( GetDvarInt( #"zombie_cheat" ) >= 5 )
{
if ( IsDefined( self.perk_hud[ perk ] ) )
{
return;
}
}
#/

if ( perk == "specialty_threeprimaries" )
{
return;
}

self waittill_any( "fake_death", "death", "player_downed" );

self UnsetPerk( perk );
self.maxhealth = 100;
self perk_hud_destroy( perk );
//self iprintln( "Perk Lost: " + perk );
}


perk_hud_create( perk )
{
if ( !IsDefined( self.perk_hud ) )
{
self.perk_hud = [];
}

/#
if ( GetDvarInt( #"zombie_cheat" ) >= 5 )
{
if ( IsDefined( self.perk_hud[ perk ] ) )
{
return;
}
}
#/


shader = "";

switch( perk )
{
case "specialty_armorvest_upgrade":
shader = "specialty_juggernaut_zombies_pro";
break;
case "specialty_armorvest":
shader = "specialty_juggernaut_zombies";
break;

case "specialty_quickrevive_upgrade":
shader = "specialty_quickrevive_zombies_pro";
break;
case "specialty_quickrevive":
shader = "specialty_quickrevive_zombies";
break;

case "specialty_fastreload_upgrade":
shader = "specialty_fastreload_zombies_pro";
break;
case "specialty_fastreload":
case "specialty_threeprimaries":
shader = "specialty_fastreload_zombies";
break;

case "specialty_rof_upgrade":
case "specialty_rof":
shader = "specialty_doubletap_zombies";
break;

default:
shader = "";
break;
}

hud = create_simple_hud( self );
hud.foreground = true;
hud.sort = 1;
hud.hidewheninmenu = false;
hud.alignX = "left";
hud.alignY = "bottom";
hud.horzAlign = "user_left";
hud.vertAlign = "user_bottom";
hud.x = self.perk_hud.size * 30;
hud.y = hud.y - 70;
hud.alpha = 1;
hud SetShader( shader, 24, 24 );

self.perk_hud[ perk ] = hud;
}


perk_hud_destroy( perk )
{
self.perk_hud[ perk ] destroy_hud();
self.perk_hud[ perk ] = undefined;
}

perk_give_bottle_begin( perk )
{
self increment_is_drinking();

self AllowLean( false );
self AllowAds( false );
self AllowSprint( false );
self AllowCrouch( true );
self AllowProne( false );
self AllowMelee( false );

wait( 0.05 );

if ( self GetStance() == "prone" )
{
self SetStance( "crouch" );
}

gun = self GetCurrentWeapon();
weapon = "";

switch( perk )
{
case "specialty_armorvest_upgrade":
case "specialty_armorvest":
weapon = "zombie_perk_bottle_jugg";
break;

case "specialty_quickrevive_upgrade":
case "specialty_quickrevive":
weapon = "zombie_perk_bottle_revive";
break;

case "specialty_fastreload_upgrade":
case "specialty_fastreload":
case "specialty_threeprimaries":
weapon = "zombie_perk_bottle_sleight";
break;

case "specialty_rof_upgrade":
case "specialty_rof":
weapon = "zombie_perk_bottle_doubletap";
break;
}

self GiveWeapon( weapon );
self SwitchToWeapon( weapon );

return gun;
}


perk_give_bottle_end( gun, perk )
{
assert( gun != "zombie_perk_bottle_doubletap" );
assert( gun != "zombie_perk_bottle_jugg" );
assert( gun != "zombie_perk_bottle_revive" );
assert( gun != "zombie_perk_bottle_sleight" );
assert( gun != "syrette_sp" );

self AllowLean( true );
self AllowAds( true );
self AllowSprint( true );
self AllowProne( true );
self AllowMelee( true );
weapon = "";
switch( perk )
{
case "specialty_rof_upgrade":
case "specialty_rof":
weapon = "zombie_perk_bottle_doubletap";
break;

case "specialty_armorvest_upgrade":
case "specialty_armorvest":
weapon = "zombie_perk_bottle_jugg";
break;

case "specialty_quickrevive_upgrade":
case "specialty_quickrevive":
weapon = "zombie_perk_bottle_revive";
break;

case "specialty_fastreload_upgrade":
case "specialty_fastreload":
case "specialty_threeprimaries":
weapon = "zombie_perk_bottle_sleight";
break;

}

// TODO: race condition?
if ( self maps\_laststand::player_is_in_laststand() || is_true( self.intermission ) )
{
self TakeWeapon(weapon);
return;
}

self decrement_is_drinking();

self TakeWeapon(weapon);

if( self is_drinking() )
{
return;
}
else if( gun != "none" && gun != "mine_bouncing_betty" && gun != "claymore_zm" )
{
self SwitchToWeapon( gun );
// ww: the knives have no first raise anim so they will never get a "weapon_change_complete" notify
// meaning it will never leave this funciton and will break buying weapons for the player
if( gun == "knife_zm" || gun == "bowie_knife_zm" )
{
return;
}
}
else
{
// try to switch to first primary weapon
primaryWeapons = self GetWeaponsListPrimaries();
if( IsDefined( primaryWeapons ) && primaryWeapons.size > 0 )
{
self SwitchToWeapon( primaryWeapons[0] );
}
}

self waittill( "weapon_change_complete" );
}

Link to comment

Zombiemode_Powerups

#include maps\_utility; 
#include common_scripts\utility;
#include maps\_zombiemode_utility;

init()
{
PrecacheShader( "specialty_doublepoints_zombies" );
PrecacheShader( "specialty_instakill_zombies" );
PrecacheShader( "specialty_firesale_zombies");
PrecacheShader( "zom_icon_bonfire");
PrecacheShader( "zom_icon_minigun");


PrecacheShader( "black" );
// powerup Vars
set_zombie_var( "zombie_insta_kill", 0 );
set_zombie_var( "zombie_point_scalar", 1 );
set_zombie_var( "zombie_drop_item", 0 );
set_zombie_var( "zombie_timer_offset", 350 ); // hud offsets
set_zombie_var( "zombie_timer_offset_interval", 30 );
set_zombie_var( "zombie_powerup_fire_sale_on", false );
set_zombie_var( "zombie_powerup_fire_sale_time", 30 );
set_zombie_var( "zombie_powerup_bonfire_sale_on", false );
set_zombie_var( "zombie_powerup_bonfire_sale_time", 30 );
set_zombie_var( "zombie_powerup_insta_kill_on", false );
set_zombie_var( "zombie_powerup_insta_kill_time", 30 ); // length of insta kill
set_zombie_var( "zombie_powerup_point_doubler_on", false );
set_zombie_var( "zombie_powerup_point_doubler_time", 30 ); // length of point doubler
// Modify by the percentage of points that the player gets
set_zombie_var( "zombie_powerup_drop_increment", 2000 ); // lower this to make drop happen more often
set_zombie_var( "zombie_powerup_drop_max_per_round", 4 ); // raise this to make drop happen more often
set_zombie_var( "zombie_powerup_minigun_on", false ); // minigun
set_zombie_var( "zombie_powerup_minigun_time", 30 );

// powerups
level._effect["powerup_on"] = loadfx( "misc/fx_zombie_powerup_on" );
level._effect["powerup_grabbed"] = loadfx( "misc/fx_zombie_powerup_grab" );
level._effect["powerup_grabbed_wave"] = loadfx( "misc/fx_zombie_powerup_wave" );
level._effect["powerup_on_red"] = loadfx( "misc/fx_zombie_powerup_on_red" );
level._effect[ "powerup_on_solo" ] = LoadFX( "misc/fx_zombie_powerup_solo_on" );
level._effect[ "powerup_grabbed_solo" ] = LoadFX( "misc/fx_zombie_powerup_solo_grab" );

if( level.mutators["mutator_noPowerups"] )
{
return;
}

init_powerups();

thread watch_for_drop();
thread setup_firesale_audio();
thread setup_bonfiresale_audio();
}

init_powerups()
{
flag_init( "zombie_drop_powerups" ); // As long as it's set, powerups will be able to spawn
flag_set( "zombie_drop_powerups" );

if( !IsDefined( level.zombie_powerup_array ) )
{
level.zombie_powerup_array = [];
}
if ( !IsDefined( level.zombie_special_drop_array ) )
{
level.zombie_special_drop_array = [];
}

// Random Drops
add_zombie_powerup( "nuke", "zombie_bomb", &"ZOMBIE_POWERUP_NUKE", "misc/fx_zombie_mini_nuke" );
// add_zombie_powerup( "nuke", "zombie_bomb", &"ZOMBIE_POWERUP_NUKE", "misc/fx_zombie_mini_nuke_hotness" );
add_zombie_powerup( "insta_kill", "zombie_skull", &"ZOMBIE_POWERUP_INSTA_KILL" );
add_zombie_powerup( "double_points","zombie_x2_icon", &"ZOMBIE_POWERUP_DOUBLE_POINTS" );
add_zombie_powerup( "full_ammo", "zombie_ammocan", &"ZOMBIE_POWERUP_MAX_AMMO");

if( !level.mutators["mutator_noBoards"] )
{
add_zombie_powerup( "carpenter", "zombie_carpenter", &"ZOMBIE_POWERUP_MAX_AMMO");
}

//GZheng - Temp VO
//add the correct VO for firesale in the 3rd parameter of this function.
if( !level.mutators["mutator_noMagicBox"] )
{
add_zombie_powerup( "fire_sale", "zombie_firesale", &"ZOMBIE_POWERUP_MAX_AMMO");
}

add_zombie_powerup( "bonfire_sale", "zombie_pickup_bonfire", &"ZOMBIE_POWERUP_MAX_AMMO");

//PI ESM - Temp VO
//TODO add the correct VO for revive all in the 3rd parameter of this function.
add_zombie_powerup( "all_revive", "zombie_revive", &"ZOMBIE_POWERUP_MAX_AMMO");

// add_zombie_special_powerup( "monkey" );

// additional special "drops"
// add_zombie_special_drop( "nothing" );
add_zombie_special_drop( "dog" );

// minigun
add_zombie_powerup( "minigun", "zombie_pickup_minigun", &"ZOMBIE_POWERUP_MINIGUN", level._effect[ "minigun_pickup" ] );

// Randomize the order
randomize_powerups();
level.zombie_powerup_index = 0;
randomize_powerups();

// Rare powerups
level.rare_powerups_active = 0;

//AUDIO: Prevents the long firesale vox from playing more than once
level.firesale_vox_firstime = false;

level thread powerup_hud_overlay();
level thread solo_powerup_hud_overlay();
}

powerup_hud_overlay()
{
level endon ("disconnect");

level.powerup_hud_array = [];
level.powerup_hud_array[0] = true;
level.powerup_hud_array[1] = true;
level.powerup_hud_array[2] = true;
level.powerup_hud_array[3] = true;
// level.powerup_hud_array[4] = true;


level.powerup_hud = [];
level.powerup_hud_cover = [];



for(i = 0; i {
level.powerup_hud[i] = create_simple_hud();
level.powerup_hud[i].foreground = true;
level.powerup_hud[i].sort = 2;
level.powerup_hud[i].hidewheninmenu = false;
level.powerup_hud[i].alignX = "center";
level.powerup_hud[i].alignY = "bottom";
level.powerup_hud[i].horzAlign = "user_center";
level.powerup_hud[i].vertAlign = "user_bottom";
level.powerup_hud[i].x = -32 + (i * 15);
level.powerup_hud[i].y = level.powerup_hud[i].y - 5; // ww: used to offset by - 78
level.powerup_hud[i].alpha = 0.8;
}

level thread Power_up_hud( "specialty_doublepoints_zombies", level.powerup_hud[0], -44, "zombie_powerup_point_doubler_time", "zombie_powerup_point_doubler_on" );
level thread Power_up_hud( "specialty_instakill_zombies", level.powerup_hud[1], -04, "zombie_powerup_insta_kill_time", "zombie_powerup_insta_kill_on" );
level thread Power_up_hud( "specialty_firesale_zombies", level.powerup_hud[2], 36, "zombie_powerup_fire_sale_time", "zombie_powerup_fire_sale_on" );
level thread Power_up_hud( "zom_icon_bonfire", level.powerup_hud[3], 116, "zombie_powerup_bonfire_sale_time", "zombie_powerup_bonfire_sale_on" );
// level thread Power_up_hud( "zom_icon_minigun", level.powerup_hud[4], 116, "zombie_powerup_minigun_time", "zombie_powerup_minigun_on" );



}
Power_up_hud( Shader, PowerUp_Hud, X_Position, PowerUp_timer, PowerUp_Var )
{

while(true)
{
if(level.zombie_vars[PowerUp_timer] {
wait(0.1);
PowerUp_Hud.alpha = 0;
wait(0.1);
}
else if(level.zombie_vars[PowerUp_timer] {
wait(0.2);
PowerUp_Hud.alpha = 0;
wait(0.18);

}

if( level.zombie_vars[PowerUp_Var] == true )
{
PowerUp_Hud.x = X_Position;
PowerUp_Hud.alpha = 1;
PowerUp_Hud setshader(Shader, 32, 32);
}
else
{
PowerUp_Hud.alpha = 0;
}

wait( 0.05 );
}
}

//** solo hud
solo_powerup_hud_overlay()
{
level endon ("disconnect");

flag_wait( "all_players_connected" );

players = get_players();

for( p = 0; p {
players[p].solo_powerup_hud_array = [];
players[p].solo_powerup_hud_array[ players[p].solo_powerup_hud_array.size ] = true;

players[p].solo_powerup_hud = [];
players[p].solo_powerup_hud_cover = [];

for(i = 0; i {
players[p].solo_powerup_hud[i] = create_simple_hud( players[p] );
players[p].solo_powerup_hud[i].foreground = true;
players[p].solo_powerup_hud[i].sort = 2;
players[p].solo_powerup_hud[i].hidewheninmenu = false;
players[p].solo_powerup_hud[i].alignX = "center";
players[p].solo_powerup_hud[i].alignY = "bottom";
players[p].solo_powerup_hud[i].horzAlign = "user_center";
players[p].solo_powerup_hud[i].vertAlign = "user_bottom";
players[p].solo_powerup_hud[i].x = -32 + (i * 15);
players[p].solo_powerup_hud[i].y = players[p].solo_powerup_hud[i].y - 5; // ww: used to offset by - 78
players[p].solo_powerup_hud[i].alpha = 0.8;
}

players[p] thread solo_power_up_hud( "zom_icon_minigun", players[p].solo_powerup_hud[0], 76, "zombie_powerup_minigun_time", "zombie_powerup_minigun_on" );
}
}

solo_power_up_hud( Shader, PowerUp_Hud, X_Position, PowerUp_timer, PowerUp_Var )
{
self endon( "disconnect" );

while(true)
{
if(level.zombie_vars[PowerUp_timer] ( IsDefined( self._show_solo_hud ) && self._show_solo_hud == true ) )
{
wait(0.1);
PowerUp_Hud.alpha = 0;
wait(0.1);
}
else if(level.zombie_vars[PowerUp_timer] ( IsDefined( self._show_solo_hud ) && self._show_solo_hud == true ) )
{
wait(0.2);
PowerUp_Hud.alpha = 0;
wait(0.18);

}

if( level.zombie_vars[PowerUp_Var] == true &&
( IsDefined( self._show_solo_hud ) && self._show_solo_hud == true ) )
{
PowerUp_Hud.x = X_Position;
PowerUp_Hud.alpha = 1;
PowerUp_Hud setshader(Shader, 32, 32);
}
else
{
PowerUp_Hud.alpha = 0;
}

wait( 0.05 );
}
}
//** solo hud


randomize_powerups()
{
level.zombie_powerup_array = array_randomize( level.zombie_powerup_array );
}

//
// Get the next powerup in the list
//
get_next_powerup()
{
powerup = level.zombie_powerup_array[ level.zombie_powerup_index ];

level.zombie_powerup_index++;
if( level.zombie_powerup_index >= level.zombie_powerup_array.size )
{
level.zombie_powerup_index = 0;
randomize_powerups();
}

return powerup;
}


//
// Figure out what the next powerup drop is
//
// Powerup Rules:
// "carpenter": Needs at least 5 windows destroyed
// "fire_sale": Needs the box to have moved
//
//
get_valid_powerup()
{
/#
if( isdefined( level.zombie_devgui_power ) && level.zombie_devgui_power == 1 )
return level.zombie_powerup_array[ level.zombie_powerup_index ];
#/

if ( isdefined( level.zombie_powerup_boss ) )
{
i = level.zombie_powerup_boss;
level.zombie_powerup_boss = undefined;
return level.zombie_powerup_array[ i ];
}

if ( isdefined( level.zombie_powerup_ape ) )
{
powerup = level.zombie_powerup_ape;
level.zombie_powerup_ape = undefined;
return powerup;
}


powerup = get_next_powerup();
while( 1 )
{
// Carpenter needs 5 destroyed windows
if( powerup == "carpenter" && get_num_window_destroyed() {
powerup = get_next_powerup();
}

// Don't bring up fire_sale if the box hasn't moved or it it's already on
else if( powerup == "fire_sale" &&
( level.zombie_vars["zombie_powerup_fire_sale_on"] == true ||
level.chest_moves {
powerup = get_next_powerup();
}
else if( powerup == "all_revive" )
{
if ( !maps\_laststand::player_num_in_laststand() ) //PI ESM - at least one player have to be down for this power-up to appear
{
powerup = get_next_powerup();
}
}
else if ( powerup == "bonfire_sale" ) // never drops with regular powerups
{
powerup = get_next_powerup();
}
else if( powerup == "minigun" && mingun_no_drop() )
{
powerup = get_next_powerup();
}
else
{
return( powerup );
}
}
}

mingun_no_drop()
{
if( level.zombie_vars[ "zombie_powerup_minigun_on" ] == true )
{
return true;
}

if( !flag( "power_on" ) )
{
if( flag( "solo_game" ) )
{
if( !flag( "solo_revive" ) )
{
return true;
}
}
else
{
return true;
}
}

return false;
}



get_num_window_destroyed()
{
num = 0;
for( i = 0; i {
/*targets = getentarray(level.exterior_goals[i].target, "targetname");

barrier_chunks = [];
for( j = 0; j {
if( IsDefined( targets[j].script_noteworthy ) )
{
if( targets[j].script_noteworthy == "clip" )
{
continue;
}
}

barrier_chunks[barrier_chunks.size] = targets[j];
}*/


if( all_chunks_destroyed( level.exterior_goals[i].barrier_chunks ) )
{
num += 1;
}

}

return num;
}

watch_for_drop()
{
flag_wait( "begin_spawning" );

players = get_players();
score_to_drop = ( players.size * level.zombie_vars["zombie_score_start_"+players.size+"p"] ) + level.zombie_vars["zombie_powerup_drop_increment"];

while (1)
{
flag_wait( "zombie_drop_powerups" );

players = get_players();

curr_total_score = 0;

for (i = 0; i {
curr_total_score += players[i].score_total;
}

if (curr_total_score > score_to_drop )
{
level.zombie_vars["zombie_powerup_drop_increment"] *= 1.14;
score_to_drop = curr_total_score + level.zombie_vars["zombie_powerup_drop_increment"];
level.zombie_vars["zombie_drop_item"] = 1;
}

wait( 0.5 );
}
}

add_zombie_powerup( powerup_name, model_name, hint, fx )
{
if( IsDefined( level.zombie_include_powerups ) && !IsDefined( level.zombie_include_powerups[powerup_name] ) )
{
return;
}

PrecacheModel( model_name );
PrecacheString( hint );

struct = SpawnStruct();

if( !IsDefined( level.zombie_powerups ) )
{
level.zombie_powerups = [];
}

struct.powerup_name = powerup_name;
struct.model_name = model_name;
struct.weapon_classname = "script_model";
struct.hint = hint;

if( IsDefined( fx ) )
{
struct.fx = LoadFx( fx );
}

level.zombie_powerups[powerup_name] = struct;
level.zombie_powerup_array[level.zombie_powerup_array.size] = powerup_name;
add_zombie_special_drop( powerup_name );
}


// special powerup list for the teleporter drop
add_zombie_special_drop( powerup_name )
{
level.zombie_special_drop_array[ level.zombie_special_drop_array.size ] = powerup_name;
}

include_zombie_powerup( powerup_name )
{
if( "1" == GetDvar( #"mutator_noPowerups") )
{
return;
}
if( !IsDefined( level.zombie_include_powerups ) )
{
level.zombie_include_powerups = [];
}

level.zombie_include_powerups[powerup_name] = true;
}

powerup_round_start()
{
level.powerup_drop_count = 0;
}

powerup_drop(drop_point)
{
if( level.mutators["mutator_noPowerups"] )
{
return;
}

if( level.powerup_drop_count >= level.zombie_vars["zombie_powerup_drop_max_per_round"] )
{
/#
println( "^3POWERUP DROP EXCEEDED THE MAX PER ROUND!" );
#/
return;
}

if( !isDefined(level.zombie_include_powerups) || level.zombie_include_powerups.size == 0 )
{
return;
}

// some guys randomly drop, but most of the time they check for the drop flag
rand_drop = randomint(100);

if (rand_drop > 2)
{
if (!level.zombie_vars["zombie_drop_item"])
{
return;
}

debug = "score";
}
else
{
debug = "random";
}

// Never drop unless in the playable area
playable_area = getentarray("player_volume","script_noteworthy");

// This needs to go above the network_safe_spawn because that has a wait.
// Otherwise, multiple threads could attempt to drop powerups.
level.powerup_drop_count++;

powerup = maps\_zombiemode_net::network_safe_spawn( "powerup", 1, "script_model", drop_point + (0,0,40));

//chris_p - fixed bug where you could not have more than 1 playable area trigger for the whole map
valid_drop = false;
for (i = 0; i {
if (powerup istouching(playable_area[i]))
{
valid_drop = true;
}
}

// If a valid drop
// We will rarely override the drop with a "rare drop" (MikeA 3/23/10)
if( valid_drop && level.rare_powerups_active )
{
pos = ( drop_point[0], drop_point[1], drop_point[2] + 42 );
if( check_for_rare_drop_override( pos ) )
{
level.zombie_vars["zombie_drop_item"] = 0;
valid_drop = 0;
}
}

// If not a valid drop, allow another spawn to be attempted
if(! valid_drop )
{
level.powerup_drop_count--;
powerup delete();
return;
}

powerup powerup_setup();

print_powerup_drop( powerup.powerup_name, debug );

powerup thread powerup_timeout();
powerup thread powerup_wobble();
powerup thread powerup_grab();

level.zombie_vars["zombie_drop_item"] = 0;

//powerup = powerup_setup();

// if is !is touching trig
// return

// spawn the model, do a ground trace and place above
// start the movement logic, spawn the fx
// start the time out logic
// start the grab logic
}


//
// Drop the specified powerup
specific_powerup_drop( powerup_name, drop_spot )
{
powerup = maps\_zombiemode_net::network_safe_spawn( "powerup", 1, "script_model", drop_spot + (0,0,40));

if ( IsDefined(powerup) )
{
struct = level.zombie_powerups[powerup_name];
powerup SetModel( struct.model_name );

//TUEY Spawn Powerup
playsoundatposition("zmb_spawn_powerup", powerup.origin);

powerup.powerup_name = struct.powerup_name;
powerup.hint = struct.hint;

if( IsDefined( struct.fx ) )
{
powerup.fx = struct.fx;
}

powerup PlayLoopSound("zmb_spawn_powerup_loop");

powerup thread powerup_timeout();
powerup thread powerup_wobble();
powerup thread powerup_grab();
}
}


//
// Special power up drop - done outside of the powerup system.
special_powerup_drop(drop_point)
{
// if( level.powerup_drop_count == level.zombie_vars["zombie_powerup_drop_max_per_round"] )
// {
// println( "^3POWERUP DROP EXCEEDED THE MAX PER ROUND!" );
// return;
// }

if( !isDefined(level.zombie_include_powerups) || level.zombie_include_powerups.size == 0 )
{
return;
}

powerup = spawn ("script_model", drop_point + (0,0,40));

// never drop unless in the playable area
playable_area = getentarray("player_volume","script_noteworthy");
//chris_p - fixed bug where you could not have more than 1 playable area trigger for the whole map
valid_drop = false;
for (i = 0; i {
if (powerup istouching(playable_area[i]))
{
valid_drop = true;
break;
}
}

if(!valid_drop)
{
powerup Delete();
return;
}

powerup special_drop_setup();
}


//
// Pick the next powerup in the list
powerup_setup()
{
powerup = get_valid_powerup();

struct = level.zombie_powerups[powerup];
self SetModel( struct.model_name );

//TUEY Spawn Powerup
playsoundatposition("zmb_spawn_powerup", self.origin);

self.powerup_name = struct.powerup_name;
self.hint = struct.hint;

if( IsDefined( struct.fx ) )
{
self.fx = struct.fx;
}

self PlayLoopSound("zmb_spawn_powerup_loop");
}


//
// Get the special teleporter drop
special_drop_setup()
{
powerup = undefined;
is_powerup = true;
// Always give something at lower rounds or if a player is in last stand mode.
if ( level.round_number {
powerup = get_valid_powerup();
}
// Gets harder now
else
{
powerup = level.zombie_special_drop_array[ RandomInt(level.zombie_special_drop_array.size) ];
if ( level.round_number > 15 &&
( RandomInt(100) {
powerup = "nothing";
}
}
//MM test Change this if you want the same thing to keep spawning
// powerup = "dog";
switch ( powerup )
{
// Don't need to do anything special
case "nuke":
case "insta_kill":
case "double_points":
case "carpenter":
case "fire_sale":
case "bonfire_sale":
case "all_revive":
case "minigun":
break;

// Limit max ammo drops because it's too powerful
case "full_ammo":
if ( level.round_number > 10 &&
( RandomInt(100) {
// Randomly pick another one
powerup = level.zombie_powerup_array[ RandomInt(level.zombie_powerup_array.size) ];
}
break;

case "dog":
if ( level.round_number >= 15 )
{
is_powerup = false;
dog_spawners = GetEntArray( "special_dog_spawner", "targetname" );
//Z2 comment out for now so we don't need to include _zombiemode_dogs
// maps\_zombiemode_dogs::special_dog_spawn( dog_spawners, 1 );
//iprintlnbold( "Samantha Sez: No Powerup For You!" );
thread play_sound_2d( "sam_nospawn" );
}
else
{
powerup = get_valid_powerup();
}
break;

// Nothing drops!!
default: // "nothing"
is_powerup = false;
Playfx( level._effect["lightning_dog_spawn"], self.origin );
playsoundatposition( "pre_spawn", self.origin );
wait( 1.5 );
playsoundatposition( "zmb_bolt", self.origin );

Earthquake( 0.5, 0.75, self.origin, 1000);
PlayRumbleOnPosition("explosion_generic", self.origin);
playsoundatposition( "spawn", self.origin );

wait( 1.0 );
//iprintlnbold( "Samantha Sez: No Powerup For You!" );
thread play_sound_2d( "sam_nospawn" );
self Delete();
}

if ( is_powerup )
{
Playfx( level._effect["lightning_dog_spawn"], self.origin );
playsoundatposition( "pre_spawn", self.origin );
wait( 1.5 );
playsoundatposition( "zmb_bolt", self.origin );

Earthquake( 0.5, 0.75, self.origin, 1000);
PlayRumbleOnPosition("explosion_generic", self.origin);
playsoundatposition( "spawn", self.origin );

// wait( 0.5 );

struct = level.zombie_powerups[powerup];
self SetModel( struct.model_name );

//TUEY Spawn Powerup
playsoundatposition("zmb_spawn_powerup", self.origin);

self.powerup_name = struct.powerup_name;
self.hint = struct.hint;

if( IsDefined( struct.fx ) )
{
self.fx = struct.fx;
}

self PlayLoopSound("zmb_spawn_powerup_loop");

self thread powerup_timeout();
self thread powerup_wobble();
self thread powerup_grab();
}
}

powerup_grab()
{
self endon ("powerup_timedout");
self endon ("powerup_grabbed");

while (isdefined(self))
{
players = get_players();

for (i = 0; i {
if( players[i] maps\_laststand::player_is_in_laststand() && self.powerup_name == "minigun" )
{
continue;
}

if (distance (players[i].origin, self.origin) {
if( IsDefined( self.powerup_name ) && self.powerup_name == "minigun" )
{
playfx (level._effect["powerup_grabbed_solo"], self.origin);
}
else
{
playfx (level._effect["powerup_grabbed"], self.origin);
}

playfx (level._effect["powerup_grabbed_wave"], self.origin);

if( IsDefined( level.zombie_powerup_grab_func ) )
{
level thread [[level.zombie_powerup_grab_func]]();
}
else
{
switch (self.powerup_name)
{
case "nuke":
level thread nuke_powerup( self );

//chrisp - adding powerup VO sounds
players[i] thread powerup_vo("nuke");
zombies = getaiarray("axis");
players[i].zombie_nuked = get_array_of_closest( self.origin, zombies );
players[i] notify("nuke_triggered");

break;
case "full_ammo":
level thread full_ammo_powerup( self );
players[i] thread powerup_vo("full_ammo");
break;
case "double_points":
level thread double_points_powerup( self );
players[i] thread powerup_vo("double_points");
break;
case "insta_kill":
level thread insta_kill_powerup( self );
players[i] thread powerup_vo("insta_kill");
break;
case "carpenter":
level thread start_carpenter( self.origin );
players[i] thread powerup_vo("carpenter");
break;

case "fire_sale":
level thread start_fire_sale( self );
players[i] thread powerup_vo("firesale");
break;

case "bonfire_sale":
level thread start_bonfire_sale( self );
players[i] thread powerup_vo("firesale");
break;

case "minigun":
level thread minigun_weapon_powerup( players[i] );
players[i] thread powerup_vo( "insta_kill" );
break;

case "all_revive":
level thread start_revive_all( self );
players[i] thread powerup_vo("revive");
break;

default:
println ("Unrecognized poweup.");
break;
}
}

wait( 0.1 );

playsoundatposition("zmb_powerup_grabbed", self.origin);
self stoploopsound();

//Preventing the line from playing AGAIN if fire sale becomes active before it runs out
if( self.powerup_name != "fire_sale" )
{
level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"][self.powerup_name] );
}

self delete();
self notify ("powerup_grabbed");
}
}
wait 0.1;
}
}

//PI ESM - revive all players in last stand on the map
start_revive_all( item )
{
players = get_players();
reviver = players[0];

for ( i = 0; i {
if ( !players[i] maps\_laststand::player_is_in_laststand() )
{
reviver = players[i];
break;
}
}

for ( i = 0; i {
if ( players[i] maps\_laststand::player_is_in_laststand() )
{
players[i] maps\_laststand::revive_force_revive( reviver );
players[i] notify ( "zombified" );
}
}
}

start_fire_sale( item )
{

level notify ("powerup fire sale");
level endon ("powerup fire sale");

level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"]["fire_sale_short"] );

level.zombie_vars["zombie_powerup_fire_sale_on"] = true;
level thread toggle_fire_sale_on();
level.zombie_vars["zombie_powerup_fire_sale_time"] = 30;

while ( level.zombie_vars["zombie_powerup_fire_sale_time"] > 0)
{
wait(0.1);
level.zombie_vars["zombie_powerup_fire_sale_time"] = level.zombie_vars["zombie_powerup_fire_sale_time"] - 0.1;
}

level.zombie_vars["zombie_powerup_fire_sale_on"] = false;
level notify ( "fire_sale_off" );

}


start_bonfire_sale( item )
{

level notify ("powerup bonfire sale");
level endon ("powerup bonfire sale");

temp_ent = spawn("script_origin", (0,0,0));
temp_ent playloopsound ("zmb_double_point_loop");

level.zombie_vars["zombie_powerup_bonfire_sale_on"] = true;
level thread toggle_bonfire_sale_on();
level.zombie_vars["zombie_powerup_bonfire_sale_time"] = 30;

while ( level.zombie_vars["zombie_powerup_bonfire_sale_time"] > 0)
{
wait(0.1);
level.zombie_vars["zombie_powerup_bonfire_sale_time"] = level.zombie_vars["zombie_powerup_bonfire_sale_time"] - 0.1;
}

level.zombie_vars["zombie_powerup_bonfire_sale_on"] = false;
level notify ( "bonfire_sale_off" );

players = get_players();
for (i = 0; i {
players[i] playsound("zmb_points_loop_off");
}

temp_ent Delete();
}


start_carpenter( origin )
{

//level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"]["carpenter"] );
window_boards = getstructarray( "exterior_goal", "targetname" );
total = level.exterior_goals.size;

//COLLIN
carp_ent = spawn("script_origin", (0,0,0));
carp_ent playloopsound( "evt_carpenter" );

while(true)
{
windows = get_closest_window_repair(window_boards, origin);
if( !IsDefined( windows ) )
{
carp_ent stoploopsound( 1 );
carp_ent playsound( "evt_carpenter_end", "sound_done" );
carp_ent waittill( "sound_done" );
break;
}

else
window_boards = array_remove(window_boards, windows);


while(1)
{
if( all_chunks_intact( windows.barrier_chunks ) )
{
break;
}

chunk = get_random_destroyed_chunk( windows.barrier_chunks );

if( !IsDefined( chunk ) )
break;

windows thread maps\_zombiemode_blockers::replace_chunk( chunk, undefined, true );
windows.clip enable_trigger();
windows.clip DisconnectPaths();
wait_network_frame();
wait(0.05);
}


wait_network_frame();

}


players = get_players();
for(i = 0; i {
players[i] maps\_zombiemode_score::player_add_points( "carpenter_powerup", 200 );
}


carp_ent delete();


}
get_closest_window_repair( windows, origin )
{
current_window = undefined;
shortest_distance = undefined;
for( i = 0; i {
if( all_chunks_intact(windows[i].barrier_chunks ) )
continue;

if( !IsDefined( current_window ) )
{
current_window = windows[i];
shortest_distance = DistanceSquared( current_window.origin, origin );

}
else
{
if( DistanceSquared(windows[i].origin, origin) {

current_window = windows[i];
shortest_distance = DistanceSquared( windows[i].origin, origin );
}

}

}

return current_window;


}

//SELF = Player
powerup_vo( type )
{
self endon("death");
self endon("disconnect");

wait(randomfloatrange(3,3.5));

self maps\_zombiemode_audio::create_and_play_dialog( "powerup", type );
}

powerup_wobble()
{
self endon ("powerup_grabbed");
self endon ("powerup_timedout");

if (isdefined(self))
{
if( IsDefined( self.powerup_name ) && self.powerup_name == "minigun" )
{
playfxontag (level._effect["powerup_on_solo"], self, "tag_origin");
}
else
{
playfxontag (level._effect["powerup_on"], self, "tag_origin");
}
}

while (isdefined(self))
{
waittime = randomfloatrange(2.5, 5);
yaw = RandomInt( 360 );
if( yaw > 300 )
{
yaw = 300;
}
else if( yaw {
yaw = 60;
}
yaw = self.angles[1] + yaw;
self rotateto ((-60 + randomint(120), yaw, -45 + randomint(90)), waittime, waittime * 0.5, waittime * 0.5);
wait randomfloat (waittime - 0.1);
}
}

powerup_timeout()
{
self endon ("powerup_grabbed");

wait 15;

for (i = 0; i {
// hide and show
if (i % 2)
{
self hide();
}
else
{
self show();
}

if (i {
wait 0.5;
}
else if (i {
wait 0.25;
}
else
{
wait 0.1;
}
}

self notify ("powerup_timedout");
self delete();
}

// kill them all!
nuke_powerup( drop_item )
{
zombies = getaispeciesarray("axis");
location = drop_item.origin;

PlayFx( drop_item.fx, location );
level thread nuke_flash();

wait( 0.5 );


zombies = get_array_of_closest( location, zombies );
zombies_nuked = [];

// Mark them for death
for (i = 0; i {
// already going to die
if ( IsDefined(zombies[i].marked_for_death) && zombies[i].marked_for_death )
{
continue;
}

// check for custom damage func
if ( IsDefined(zombies[i].nuke_damage_func) )
{
zombies[i] thread [[ zombies[i].nuke_damage_func ]]();
continue;
}

if( is_magic_bullet_shield_enabled( zombies[i] ) )
{
continue;
}

zombies[i].marked_for_death = true;
zombies[i].nuked = true;
zombies_nuked[ zombies_nuked.size ] = zombies[i];
}

for (i = 0; i {
wait (randomfloatrange(0.1, 0.7));
if( !IsDefined( zombies_nuked[i] ) )
{
continue;
}

if( is_magic_bullet_shield_enabled( zombies_nuked[i] ) )
{
continue;
}

if( i {
zombies_nuked[i] thread animscripts\zombie_death::flame_death_fx();
zombies_nuked[i] playsound ("evt_nuked");

}

if( !( zombies_nuked[i].isdog ) )
{
zombies_nuked[i] maps\_zombiemode_spawner::zombie_head_gib();
zombies_nuked[i] playsound ("evt_nuked");
}


zombies_nuked[i] dodamage( zombies_nuked[i].health + 666, zombies_nuked[i].origin );
}

players = get_players();
for(i = 0; i {
players[i] maps\_zombiemode_score::player_add_points( "nuke_powerup", 400 );
}
}

nuke_flash()
{
players = getplayers();
for(i=0; i {
players[i] play_sound_2d("evt_nuke_flash");
}
level thread devil_dialog_delay();


fadetowhite = newhudelem();

fadetowhite.x = 0;
fadetowhite.y = 0;
fadetowhite.alpha = 0;

fadetowhite.horzAlign = "fullscreen";
fadetowhite.vertAlign = "fullscreen";
fadetowhite.foreground = true;
fadetowhite SetShader( "white", 640, 480 );

// Fade into white
fadetowhite FadeOverTime( 0.2 );
fadetowhite.alpha = 0.8;

wait 0.5;
fadetowhite FadeOverTime( 1.0 );
fadetowhite.alpha = 0;

wait 1.1;
fadetowhite destroy();
}


// double the points
double_points_powerup( drop_item )
{
level notify ("powerup points scaled");
level endon ("powerup points scaled");

// players = get_players();
// array_thread(level,::point_doubler_on_hud, drop_item);
level thread point_doubler_on_hud( drop_item );

level.zombie_vars["zombie_point_scalar"] = 2;
wait 30;

level.zombie_vars["zombie_point_scalar"] = 1;
}

full_ammo_powerup( drop_item )
{
players = get_players();
for (i = 0; i {
primary_weapons = players[i] GetWeaponsList();

for( x = 0; x {
// Fill the clip
//players[i] SetWeaponAmmoClip( primary_weapons[x], WeaponClipSize( primary_weapons[x] ) );

players[i] notify( "zmb_lost_knife" );
players[i] notify( "zmb_disable_claymore_prompt" );
players[i] GiveMaxAmmo( primary_weapons[x] );
}
}
// array_thread (players, ::full_ammo_on_hud, drop_item);
level thread full_ammo_on_hud( drop_item );
}

insta_kill_powerup( drop_item )
{
level notify( "powerup instakill" );
level endon( "powerup instakill" );


// array_thread (players, ::insta_kill_on_hud, drop_item);
level thread insta_kill_on_hud( drop_item );

level.zombie_vars["zombie_insta_kill"] = 1;
wait( 30 );
level.zombie_vars["zombie_insta_kill"] = 0;
players = get_players();
for(i = 0; i {
players[i] notify("insta_kill_over");

}

}

check_for_instakill( player, mod, hit_location )
{
if( level.mutators["mutator_noPowerups"] )
{
return;
}
if( IsDefined( player ) && IsAlive( player ) && level.zombie_vars["zombie_insta_kill"])
{
if( is_magic_bullet_shield_enabled( self ) )
{
return;
}

if( IsDefined(self.animname) && self.animname == "ape_zombie" )
{
return;
}

if(player.use_weapon_type == "MOD_MELEE")
{
player.last_kill_method = "MOD_MELEE";
}
else
{
player.last_kill_method = "MOD_UNKNOWN";

}

modName = remove_mod_from_methodofdeath( mod );
if( flag( "dog_round" ) )
{
self DoDamage( self.health * 10, self.origin, player, undefined, modName, hit_location );
player notify("zombie_killed");
}
else
{
self maps\_zombiemode_spawner::zombie_head_gib();
self DoDamage( self.health * 10, self.origin, player, undefined, modName, hit_location );
player notify("zombie_killed");

}
}
}

insta_kill_on_hud( drop_item )
{
self endon ("disconnect");

// check to see if this is on or not
if ( level.zombie_vars["zombie_powerup_insta_kill_on"] )
{
// reset the time and keep going
level.zombie_vars["zombie_powerup_insta_kill_time"] = 30;
return;
}

level.zombie_vars["zombie_powerup_insta_kill_on"] = true;

// set up the hudelem
//hudelem = maps\_hud_util::createFontString( "objective", 2 );
//hudelem maps\_hud_util::setPoint( "TOP", undefined, 0, level.zombie_vars["zombie_timer_offset"] + level.zombie_vars["zombie_timer_offset_interval"]);
//hudelem.sort = 0.5;
//hudelem.alpha = 0;
//hudelem fadeovertime(0.5);
//hudelem.alpha = 1;
//hudelem.label = drop_item.hint;

// set time remaining for insta kill
level thread time_remaning_on_insta_kill_powerup();

// offset in case we get another powerup
//level.zombie_timer_offset -= level.zombie_timer_offset_interval;
}

time_remaning_on_insta_kill_powerup()
{
//self setvalue( level.zombie_vars["zombie_powerup_insta_kill_time"] );
//level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"]["instakill"] );
temp_enta = spawn("script_origin", (0,0,0));
temp_enta playloopsound("zmb_insta_kill_loop");

/*
players = get_players();
for (i = 0; i {
players[i] playloopsound ("zmb_insta_kill_loop");
}
*/


// time it down!
while ( level.zombie_vars["zombie_powerup_insta_kill_time"] >= 0)
{
wait 0.1;
level.zombie_vars["zombie_powerup_insta_kill_time"] = level.zombie_vars["zombie_powerup_insta_kill_time"] - 0.1;
// self setvalue( level.zombie_vars["zombie_powerup_insta_kill_time"] );
}

players = get_players();
for (i = 0; i {
//players[i] stoploopsound (2);

players[i] playsound("zmb_insta_kill");

}

temp_enta stoploopsound(2);
// turn off the timer
level.zombie_vars["zombie_powerup_insta_kill_on"] = false;

// remove the offset to make room for new powerups, reset timer for next time
level.zombie_vars["zombie_powerup_insta_kill_time"] = 30;
//level.zombie_timer_offset += level.zombie_timer_offset_interval;
//self destroy();
temp_enta delete();
}

point_doubler_on_hud( drop_item )
{
self endon ("disconnect");

// check to see if this is on or not
if ( level.zombie_vars["zombie_powerup_point_doubler_on"] )
{
// reset the time and keep going
level.zombie_vars["zombie_powerup_point_doubler_time"] = 30;
return;
}

level.zombie_vars["zombie_powerup_point_doubler_on"] = true;
//level.powerup_hud_array[0] = true;
// set up the hudelem
//hudelem = maps\_hud_util::createFontString( "objective", 2 );
//hudelem maps\_hud_util::setPoint( "TOP", undefined, 0, level.zombie_vars["zombie_timer_offset"] );
//hudelem.sort = 0.5;
//hudelem.alpha = 0;
//hudelem fadeovertime( 0.5 );
//hudelem.alpha = 1;
//hudelem.label = drop_item.hint;

// set time remaining for point doubler
level thread time_remaining_on_point_doubler_powerup();

// offset in case we get another powerup
//level.zombie_timer_offset -= level.zombie_timer_offset_interval;
}

time_remaining_on_point_doubler_powerup()
{
//self setvalue( level.zombie_vars["zombie_powerup_point_doubler_time"] );

temp_ent = spawn("script_origin", (0,0,0));
temp_ent playloopsound ("zmb_double_point_loop");

//level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"]["doublepoints"] );


// time it down!
while ( level.zombie_vars["zombie_powerup_point_doubler_time"] >= 0)
{
wait 0.1;
level.zombie_vars["zombie_powerup_point_doubler_time"] = level.zombie_vars["zombie_powerup_point_doubler_time"] - 0.1;
//self setvalue( level.zombie_vars["zombie_powerup_point_doubler_time"] );
}

// turn off the timer
level.zombie_vars["zombie_powerup_point_doubler_on"] = false;
players = get_players();
for (i = 0; i {
//players[i] stoploopsound("zmb_double_point_loop", 2);
players[i] playsound("zmb_points_loop_off");
}
temp_ent stoploopsound(2);


// remove the offset to make room for new powerups, reset timer for next time
level.zombie_vars["zombie_powerup_point_doubler_time"] = 30;
//level.zombie_timer_offset += level.zombie_timer_offset_interval;
//self destroy();
temp_ent delete();
}
toggle_bonfire_sale_on()
{
level endon ("powerup bonfire sale");

if( !isdefined ( level.zombie_vars["zombie_powerup_bonfire_sale_on"] ) )
{
return;
}

if( level.zombie_vars["zombie_powerup_bonfire_sale_on"] )
{
if ( isdefined( level.bonfire_init_func ) )
{
level thread [[ level.bonfire_init_func ]]();
}
level waittill( "bonfire_sale_off" );
}
}
toggle_fire_sale_on()
{
level endon ("powerup fire sale");

if( !isdefined ( level.zombie_vars["zombie_powerup_fire_sale_on"] ) )
{
return;
}

if( level.zombie_vars["zombie_powerup_fire_sale_on"] )
{
for( i = 0; i {
level.chests[i].zombie_cost = 10;
level.chests[i] set_hint_string( level.chests[i] , "powerup_fire_sale_cost" );

if( level.chest_index != i )
{
level.chests[i] thread maps\_zombiemode_weapons::show_chest();
level.chests[i] thread maps\_zombiemode_weapons::hide_rubble();
wait_network_frame();
}
}
level waittill( "fire_sale_off" );

for( i = 0; i {
if( level.chest_index != i )
{
level thread remove_temp_chest( i );
}

if(IsDefined(level.chests[i].grab_weapon_hint) && (level.chests[i].grab_weapon_hint == true))
{
level.chests[i] thread fire_sale_weapon_wait();
}
else
{
level.chests[i].zombie_cost = level.chests[i].old_cost;
level.chests[i] set_hint_string( level.chests[i] , "default_treasure_chest_" + level.chests[i].zombie_cost );
}
}

}

}
//-------------------------------------------------------------------------------
// DCS: Adding check if box is open to grab weapon when fire sale ends.
//-------------------------------------------------------------------------------
fire_sale_weapon_wait()
{
self.zombie_cost = self.old_cost;
while( isdefined( self.chest_user ) )
{
wait_network_frame();
}
self set_hint_string( self , "default_treasure_chest_" + self.zombie_cost );
}

//
// Bring the chests back to normal.
remove_temp_chest( chest_index )
{
while( isdefined( level.chests[chest_index].chest_user ) || (IsDefined(level.chests[chest_index]._box_open) && level.chests[chest_index]._box_open == true))
{
wait_network_frame();
}
playfx(level._effect["poltergeist"], level.chests[chest_index].orig_origin);
level.chests[chest_index] playsound ( "zmb_box_poof_land" );
level.chests[chest_index] playsound( "zmb_couch_slam" );
level.chests[chest_index] maps\_zombiemode_weapons::hide_chest();
level.chests[chest_index] maps\_zombiemode_weapons::show_rubble();
}


devil_dialog_delay()
{
wait(1.0);
//level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"]["nuke"] );
}

full_ammo_on_hud( drop_item )
{
self endon ("disconnect");

// set up the hudelem
hudelem = maps\_hud_util::createFontString( "objective", 2 );
hudelem maps\_hud_util::setPoint( "TOP", undefined, 0, level.zombie_vars["zombie_timer_offset"] - (level.zombie_vars["zombie_timer_offset_interval"] * 2));
hudelem.sort = 0.5;
hudelem.alpha = 0;
hudelem fadeovertime(0.5);
hudelem.alpha = 1;
hudelem.label = drop_item.hint;

// set time remaining for insta kill
hudelem thread full_ammo_move_hud();

// offset in case we get another powerup
//level.zombie_timer_offset -= level.zombie_timer_offset_interval;
}

full_ammo_move_hud()
{

players = get_players();
//level thread maps\_zombiemode_audio::do_announcer_playvox( level.devil_vox["powerup"]["maxammo"] );
for (i = 0; i {
players[i] playsound ("zmb_full_ammo");

}
wait 0.5;
move_fade_time = 1.5;

self FadeOverTime( move_fade_time );
self MoveOverTime( move_fade_time );
self.y = 270;
self.alpha = 0;

wait move_fade_time;

self destroy();
}


//*****************************************************************************
// Here we have a selection of special case rare powerups that may get dropped
// by the random powerup generator
//*****************************************************************************
check_for_rare_drop_override( pos )
{
if( IsDefined(flag("ape_round")) && flag("ape_round") )
{
return( 0 );
}

return( 0 );
}
setup_firesale_audio()
{
wait(2);

intercom = getentarray ("intercom", "targetname");
while(1)
{
while( level.zombie_vars["zombie_powerup_fire_sale_on"] == false)
{
wait(0.2);
}
for(i=0;i {
intercom[i] thread play_firesale_audio();
//PlaySoundatposition( "zmb_vox_ann_firesale", intercom[i].origin );
}
while( level.zombie_vars["zombie_powerup_fire_sale_on"] == true)
{
wait (0.1);
}
level notify ("firesale_over");
}
}
play_firesale_audio()
{
self playloopsound ("mus_fire_sale");
level waittill ("firesale_over");
self stoploopsound ();

}

setup_bonfiresale_audio()
{
wait(2);

intercom = getentarray ("intercom", "targetname");
while(1)
{
while( level.zombie_vars["zombie_powerup_fire_sale_on"] == false)
{
wait(0.2);
}
for(i=0;i {
intercom[i] thread play_bonfiresale_audio();
//PlaySoundatposition( "zmb_vox_ann_firesale", intercom[i].origin );
}
while( level.zombie_vars["zombie_powerup_fire_sale_on"] == true)
{
wait (0.1);
}
level notify ("firesale_over");
}
}
play_bonfiresale_audio()
{
self playloopsound ("mus_fire_sale");
level waittill ("firesale_over");
self stoploopsound ();

}

//******************************************************************************
// Minigun powerup
//******************************************************************************
minigun_weapon_powerup( ent_player )
{
self endon( "disconnect" );
ent_player endon( "death" );
ent_player endon( "player_downed" );

ent_player._show_solo_hud = true;

// make sure weapons are replaced properly if the player is downed
level._zombie_minigun_powerup_last_stand_func = ::minigun_watch_gunner_downed;

ent_player increment_is_drinking();
ent_player._zombie_gun_before_minigun = ent_player GetCurrentWeapon();

// give player a minigun
ent_player GiveWeapon( "minigun_zm" );
ent_player SwitchToWeapon( "minigun_zm" );

level.zombie_vars[ "zombie_powerup_minigun_on" ] = true;

level thread minigun_weapon_powerup_countdown( ent_player, "minigun_time_over" );

}

minigun_weapon_powerup_countdown( ent_player, str_gun_return_notify )
{
ent_player endon( "death" );
ent_player endon( "player_downed" );
ent_player endon( str_gun_return_notify );

time_passed = 0;

//AUDIO: Starting powerup loop on ONLY this player
setClientSysState( "levelNotify", "minis", ent_player );

level.zombie_vars["zombie_powerup_minigun_time"] = 30;
while ( level.zombie_vars["zombie_powerup_minigun_time"] > 0)
{
wait(0.1);
level.zombie_vars["zombie_powerup_minigun_time"] = level.zombie_vars["zombie_powerup_minigun_time"] - 0.1;
}

//AUDIO: Ending powerup loop on ONLY this player
setClientSysState( "levelNotify", "minie", ent_player );

level thread minigun_weapon_powerup_remove( ent_player, str_gun_return_notify );

}

minigun_weapon_powerup_remove( ent_player, str_gun_return_notify )
{
ent_player endon( "death" );
ent_player endon( "player_downed" );

// take the minigun back
ent_player TakeWeapon( "minigun_zm" );

level.zombie_vars[ "zombie_powerup_minigun_on" ] = false;
ent_player._show_solo_hud = false;

level._zombie_minigun_powerup_last_stand_func = undefined;

// this gives the player back their weapons
ent_player notify( str_gun_return_notify );

ent_player decrement_is_drinking();

if( IsDefined( ent_player._zombie_gun_before_minigun ) )
{
player_weapons = ent_player GetWeaponsListPrimaries();
for( i = 0; i {
if( player_weapons[i] == ent_player._zombie_gun_before_minigun )
{
ent_player SwitchToWeapon( ent_player._zombie_gun_before_minigun );
return;
}
}
}

// if the player got through all that without getting a weapon back give them the first one
primaryWeapons = ent_player GetWeaponsListPrimaries();
if( primaryWeapons.size > 0 )
{
ent_player SwitchToWeapon( primaryWeapons[0] );
}
else
{
allWeapons = ent_player GetWeaponsList();
for( i = 0; i {
if( allWeapons[i] == "knife_zm" || allWeapons[i] == "bowie_knife_zm" )
{
ent_player SwitchToWeapon( allWeapons[i] );
return;
}
}
}

}

minigun_weapon_powerup_off()
{
level.zombie_vars["zombie_powerup_minigun_time"] = 0;
}

minigun_watch_gunner_downed()
{
primaryWeapons = self GetWeaponsListPrimaries();

for( i = 0; i {
if( primaryWeapons[i] == "minigun_zm" )
{
self TakeWeapon( "minigun_zm" );
}
}

// self decrement_is_drinking();

// this gives the player back their weapons
self notify( "minigun_time_over" );

level.zombie_vars[ "zombie_powerup_minigun_on" ] = false;
self._show_solo_hud = false;



level._zombie_minigun_powerup_last_stand_func = undefined;
}


//******************************************************************************
//
// DEBUG
//
print_powerup_drop( powerup, type )
{
/#
if( !IsDefined( level.powerup_drop_time ) )
{
level.powerup_drop_time = 0;
level.powerup_random_count = 0;
level.powerup_score_count = 0;
}

time = ( GetTime() - level.powerup_drop_time ) * 0.001;
level.powerup_drop_time = GetTime();

if( type == "random" )
{
level.powerup_random_count++;
}
else
{
level.powerup_score_count++;
}

println( "========== POWER UP DROPPED ==========" );
println( "DROPPED: " + powerup );
println( "HOW IT DROPPED: " + type );
println( "--------------------" );
println( "Drop Time: " + time );
println( "Random Powerup Count: " + level.powerup_random_count );
println( "Random Powerup Count: " + level.powerup_score_count );
println( "======================================" );
#/
}

there is plenty more...but I don't have the time right now. I'll get you the rest later.

Link to comment

I took a few college C++ classes...

I didn't see anything too exciting as far as easter eggs ,but there are a few interesting things in the Audio files:

There are files for the Bon Fire Sale as well as the Death Machine, neither of which are available on this map.

Also it contains sound files for the "tesla gun" as well as the "freezegun". Originally I thought the tesla gun was the thunder gun, however it also has files for the thunder gun in the same section as the tesla gun, so it must be something different.

I'll look into it a little more, but these were a few things i noticed right away.

Link to comment

I took a few college C++ classes...

I didn't see anything too exciting as far as easter eggs ,but there are a few interesting things in the Audio files:

There are files for the Bon Fire Sale as well as the Death Machine, neither of which are available on this map.

Also it contains sound files for the "tesla gun" as well as the "freezegun". Originally I thought the tesla gun was the thunder gun, however it also has files for the thunder gun in the same section as the tesla gun, so it must be something different.

I'll look into it a little more, but these were a few things i noticed right away.

switch( meansofdeath )

{

case "melee": chance = 75; break;

case "melee_instakill": chance = 99; break;

case "weapon_instakill": chance = 10; break;

case "explosive": chance = 60; break;

case "flame": chance = 60; break;

case "raygun": chance = 75; break;

case "headshot": chance = 99; break;

case "crawler": chance = 30; break;

case "quad": chance = 30; break;

case "closekill": chance = 15; break;

case "bullet": chance = 10; break;

case "default": chance = 10; break;

}

Interesting indeed a nice percentage chart.

Link to comment

//EGGS and OTHER STUFF: Egg lines, achievements, etc

level.plr_vox["eggs"] = [];

level.plr_vox["eggs"]["achievement"] = "achievement";

level.plr_vox["eggs"]["music_activate"] = "secret";

level.plr_vox["eggs"]["meteors"] = "egg_pedastool";

level.plr_vox["eggs"]["room_screen"] = "egg_room_screen";

level.plr_vox["eggs"]["room_dress"] = "egg_room_dress";

level.plr_vox["eggs"]["room_lounge"] = "egg_room_lounge";

level.plr_vox["eggs"]["room_rest"] = "egg_room_rest";

level.plr_vox["eggs"]["room_alley"] = "egg_room_alley";

level.plr_vox["eggs"]["portrait_dempsey"] = "egg_port_dempsey";

level.plr_vox["eggs"]["portrait_nikolai"] = "egg_port_nikolai";

level.plr_vox["eggs"]["portrait_takeo"] = "egg_port_takeo";

level.plr_vox["eggs"]["portrait_richtofan"] = "egg_port_richtofan";

level.plr_vox["eggs"]["portrait_empty"] = "egg_port_empty";

What does this mean!

level.plr_vox["eggs"]["room_screen"] = "egg_room_screen";

level.plr_vox["eggs"]["room_dress"] = "egg_room_dress";

level.plr_vox["eggs"]["room_lounge"] = "egg_room_lounge";

level.plr_vox["eggs"]["room_rest"] = "egg_room_rest";

level.plr_vox["eggs"]["room_alley"] = "egg_room_alley"

Locations for new audio tape?

Link to comment

He is talking about the programming code... I also think there are some easter eggs we have not found.

Kino Der Toten means Movies Of The Dead.

no it means theater of the damned

Nope, it's Cinema of the Dead. or Theater of the Dead. I'm German so I know these names.

btw.

i just found this in Zombiemode_aiaudio

" level.devil_vox["powerup"]["carpenter"] = "carpenter";

level.devil_vox["powerup"]["insta_kill"] = "instakill";

level.devil_vox["powerup"]["double_points"] = "doublepoints";

level.devil_vox["powerup"]["nuke"] = "nuke";

level.devil_vox["powerup"]["full_ammo"] = "maxammo";

level.devil_vox["powerup"]["fire_sale"] = "firesale";

level.devil_vox["powerup"]["fire_sale_short"] = "firesale_short";

level.devil_vox["powerup"]["minigun"] = "death_machine";

level.devil_vox["powerup"]["bonfire_sale"] = "bonfiresale";

level.devil_vox["powerup"]["all_revive"] = undefined;"

Deathmachine and All Revive?

Are all of those codes for Kino, or all three starter maps? is there rleally a All Revive? lol.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use, Privacy Policy, Code of Conduct, We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. .