burc_2004

_zombiemode.gsc

Jul 19th, 2015
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include maps\_anim;
  2. #include maps\_utility;
  3. #include common_scripts\utility;
  4. #include maps\_music;
  5. #include maps\_zombiemode_utility;
  6. #include maps\_busing;
  7.  
  8. #using_animtree( "generic_human" );
  9.  
  10. main()
  11. {
  12.     level.player_too_many_weapons_monitor = true;
  13.     level.player_too_many_weapons_monitor_func = ::player_too_many_weapons_monitor;
  14.     level._dontInitNotifyMessage = 1;
  15.    
  16.     init_additionalprimaryweapon_machine_locations();
  17.  
  18.     // put things you'd like to be able to turn off in here above this line
  19.     level thread maps\_zombiemode_ffotd::main_start();
  20.  
  21.     level.zombiemode = true;
  22.     level.reviveFeature = false;
  23.     level.contextualMeleeFeature = false;
  24.     level.swimmingFeature = false;
  25.     level.calc_closest_player_using_paths = true;
  26.     level.zombie_melee_in_water = true;
  27.     level.put_timed_out_zombies_back_in_queue = true;
  28.     level.use_alternate_poi_positioning = true;
  29.    
  30.     //for tracking stats
  31.     level.zombies_timeout_spawn = 0;
  32.     level.zombies_timeout_playspace = 0;
  33.     level.zombies_timeout_undamaged = 0;   
  34.     level.zombie_player_killed_count = 0;
  35.     level.zombie_trap_killed_count = 0;
  36.     level.zombie_pathing_failed = 0;
  37.     level.zombie_breadcrumb_failed = 0;
  38.  
  39.     level.zombie_visionset = "zombie_neutral";
  40.  
  41.     if(GetDvar("anim_intro") == "1")
  42.     {
  43.         level.zombie_anim_intro = 1;
  44.     }
  45.     else
  46.     {
  47.         level.zombie_anim_intro = 0;
  48.     }
  49.  
  50.     precache_shaders();
  51.     precache_models();
  52.  
  53.     PrecacheItem( "frag_grenade_zm" );
  54.     PrecacheItem( "claymore_zm" );
  55.  
  56.     //override difficulty
  57.     level.skill_override = 1;
  58.     maps\_gameskill::setSkill(undefined,level.skill_override);
  59.    
  60.     level.disable_player_damage_knockback = true;
  61.  
  62.     level._ZOMBIE_GIB_PIECE_INDEX_ALL = 0;
  63.     level._ZOMBIE_GIB_PIECE_INDEX_RIGHT_ARM = 1;
  64.     level._ZOMBIE_GIB_PIECE_INDEX_LEFT_ARM = 2;
  65.     level._ZOMBIE_GIB_PIECE_INDEX_RIGHT_LEG = 3;
  66.     level._ZOMBIE_GIB_PIECE_INDEX_LEFT_LEG = 4;
  67.     level._ZOMBIE_GIB_PIECE_INDEX_HEAD = 5;
  68.     level._ZOMBIE_GIB_PIECE_INDEX_GUTS = 6;
  69.  
  70.     init_dvars();
  71.     init_mutators();
  72.     init_strings();
  73.     init_levelvars();
  74.     init_animscripts();
  75.     init_sounds();
  76.     init_shellshocks();
  77.     init_flags();
  78.     init_client_flags();
  79.  
  80.     register_offhand_weapons_for_level_defaults();
  81.  
  82.     //Limit zombie to 24 max, must have for network purposes
  83.     if ( !isdefined( level.zombie_ai_limit ) )
  84.     {
  85.         level.zombie_ai_limit = 24;
  86.         SetAILimit( level.zombie_ai_limit );
  87.     }
  88.  
  89.     init_fx();
  90.     //maps\_zombiemode_ability::init();
  91.  
  92.     // load map defaults  
  93.     maps\_zombiemode_load::main();
  94.  
  95.     // Initialize the zone manager above any scripts that make use of zone info
  96.     maps\_zombiemode_zone_manager::init();
  97.  
  98.     // Call the other zombiemode scripts
  99.     maps\_zombiemode_audio::audio_init();
  100.     maps\_zombiemode_claymore::init();
  101.     maps\_zombiemode_weapons::init();
  102.     maps\_zombiemode_equipment::init();
  103.     maps\_zombiemode_blockers::init();
  104.     maps\_zombiemode_spawner::init();
  105.     maps\_zombiemode_powerups::init();
  106.     maps\_zombiemode_perks::init();
  107.     maps\_zombiemode_user::init();
  108.     maps\_zombiemode_weap_cymbal_monkey::init();
  109.     maps\_zombiemode_weap_freezegun::init();
  110.     maps\_zombiemode_weap_tesla::init();
  111.     maps\_zombiemode_weap_thundergun::init();
  112.     maps\_zombiemode_weap_crossbow::init();
  113. //Z2    TEMP DISABLE DURING INTEGRATION
  114.     maps\_zombiemode_bowie::bowie_init();
  115. //  maps\_zombiemode_betty::init();
  116. //  maps\_zombiemode_timer::init();
  117. //  maps\_zombiemode_auto_turret::init();
  118.     //maps\_zombiemode_protips::pro_tips_initialize();
  119.     maps\_zombiemode_traps::init();
  120.     maps\_zombiemode_weapon_box::init();
  121.     /#
  122.     maps\_zombiemode_devgui::init();
  123.     #/
  124.  
  125.     init_function_overrides();
  126.    
  127.     // ww: init the pistols in the game so last stand has the importance order
  128.     level thread last_stand_pistol_rank_init();
  129.  
  130.     //thread maps\_zombiemode_rank::init();
  131.  
  132.     // These MUST be threaded because they contain waits
  133.     //level thread maps\_zombiemode_deathcard::init();
  134.     //level thread maps\_zombiemode_money::init();
  135.     level thread [[level.Player_Spawn_func]]();
  136.     level thread onPlayerConnect();
  137.     level thread post_all_players_connected();
  138.    
  139.     init_utility();
  140.     maps\_utility::registerClientSys("zombify");    // register a client system...
  141.     init_anims();   // zombie ai and anim inits
  142.  
  143.     if( isDefined( level.custom_ai_type ) )
  144.     {
  145.         for( i = 0; i < level.custom_ai_type.size; i++ )
  146.         {
  147.             [[ level.custom_ai_type[i] ]]();
  148.         }
  149.     }
  150.    
  151.     if( level.mutators[ "mutator_friendlyFire" ] )
  152.     {
  153.         SetDvar( "friendlyfire_enabled", "1" );
  154.     }
  155.    
  156.     initZombieLeaderboardData();
  157.     initializeStatTracking();  
  158.    
  159.     if ( GetPlayers().size <= 1 )
  160.     {
  161.         incrementCounter( "global_solo_games", 1 );
  162.     }
  163.     else if( level.systemLink )
  164.     {
  165.         incrementCounter( "global_systemlink_games", 1 );
  166.     }
  167.     else if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
  168.     {
  169.         incrementCounter( "global_splitscreen_games", 1 );
  170.     }
  171.     else // coop game
  172.     {
  173.         incrementCounter( "global_coop_games", 1 );
  174.     }
  175.    
  176.     // Fog in splitscreen
  177.     if( IsSplitScreen() )
  178.     {
  179.         set_splitscreen_fog( 350, 2986.33, 10000, -480, 0.805, 0.715, 0.61, 0.0, 10000 );
  180.     }
  181.    
  182.     /#
  183.     init_screen_stats();
  184.     level thread update_screen_stats();
  185.     #/
  186.  
  187.     level thread maps\_zombiemode_ffotd::main_end();
  188. }
  189.  
  190. post_all_players_connected()
  191. {
  192.     flag_wait( "all_players_connected" );
  193. /#
  194.     execdevgui( "devgui_zombie" );
  195. #/
  196.     println( "sessions: mapname=", level.script, " gametype zom isserver 1 player_count=", get_players().size );
  197.  
  198.    
  199.     maps\_zombiemode_score::init();
  200.     level difficulty_init();
  201.  
  202.     //thread zombie_difficulty_ramp_up();
  203.  
  204.     // DCS 091610: clear up blood patches when set to mature.
  205.     level thread clear_mature_blood();
  206.  
  207.     // Start the Zombie MODE!
  208.     level thread end_game();
  209.    
  210.     if(!level.zombie_anim_intro)
  211.     {
  212.         level thread round_start();
  213.     }
  214.     level thread players_playing();
  215.     if ( IsDefined( level.crawlers_enabled ) && level.crawlers_enabled == 1 )
  216.     {
  217.         level thread crawler_round_tracker();
  218.     }
  219.  
  220.     //chrisp - adding spawning vo
  221.     //level thread spawn_vo();
  222.    
  223.     //add ammo tracker for VO
  224.     level thread track_players_ammo_count();
  225.    
  226.     //level thread prevent_near_origin();
  227.  
  228.     DisableGrenadeSuicide();
  229.  
  230.     level.startInvulnerableTime = GetDvarInt( #"player_deathInvulnerableTime" );
  231. //  level.global_damage_func        = maps\_zombiemode_spawner::zombie_damage;
  232. //  level.global_damage_func_ads    = maps\_zombiemode_spawner::zombie_damage_ads;
  233.  
  234.     // TESTING
  235.     //  wait( 3 );
  236.     //  level thread intermission();
  237.     //  thread testing_spawner_bug();
  238.  
  239.     if(!IsDefined(level.music_override) )
  240.     {
  241.         level.music_override = false;
  242.     }
  243. }
  244.  
  245. zombiemode_melee_miss()
  246. {
  247.     if( isDefined( self.enemy.curr_pay_turret ) )
  248.     {
  249.         self.enemy doDamage( GetDvarInt( #"ai_meleeDamage" ), self.origin, self, undefined, "melee", "none" );
  250.     }
  251. }
  252.  
  253. init_additionalprimaryweapon_machine_locations()
  254. {
  255.     switch ( Tolower( GetDvar( #"mapname" ) ) )
  256.     {
  257.     case "zombie_theater":
  258.         level.zombie_additionalprimaryweapon_machine_origin = (1172.4, -359.7, 320);
  259.         level.zombie_additionalprimaryweapon_machine_angles = (0, 90, 0);
  260.         level.zombie_additionalprimaryweapon_machine_clip_origin = (1160, -360, 448);
  261.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 0, 0);
  262.         break;
  263.     case "zombie_pentagon":
  264.         level.zombie_additionalprimaryweapon_machine_origin = (-1081.4, 1496.9, -512);
  265.         level.zombie_additionalprimaryweapon_machine_angles = (0, 162.2, 0);
  266.         level.zombie_additionalprimaryweapon_machine_clip_origin = (-1084, 1489, -448);
  267.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 341.4, 0);
  268.         break;
  269.     case "zombie_cosmodrome":
  270.         level.zombie_additionalprimaryweapon_machine_origin = (420.8, 1359.1, 55);
  271.         level.zombie_additionalprimaryweapon_machine_angles = (0, 270, 0);
  272.         level.zombie_additionalprimaryweapon_machine_clip_origin = (436, 1359, 177);
  273.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 0, 0);
  274.  
  275.         level.zombie_additionalprimaryweapon_machine_monkey_angles = (0, 0, 0);
  276.         level.zombie_additionalprimaryweapon_machine_monkey_origins = [];
  277.         level.zombie_additionalprimaryweapon_machine_monkey_origins[0] = (398.8, 1398.6, 60);
  278.         level.zombie_additionalprimaryweapon_machine_monkey_origins[1] = (380.8, 1358.6, 60);
  279.         level.zombie_additionalprimaryweapon_machine_monkey_origins[2] = (398.8, 1318.6, 60);
  280.         break;
  281.     case "zombie_coast":
  282.         level.zombie_additionalprimaryweapon_machine_origin = (2424.4, -2884.3, 314);
  283.         level.zombie_additionalprimaryweapon_machine_angles = (0, 231.6, 0);
  284.         level.zombie_additionalprimaryweapon_machine_clip_origin = (2435, -2893, 439);
  285.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 322.2, 0);
  286.         break;
  287.     case "zombie_temple":
  288.         level.zombie_additionalprimaryweapon_machine_origin = (-1352.9, -1437.2, -485);
  289.         level.zombie_additionalprimaryweapon_machine_angles = (0, 297.8, 0);
  290.         level.zombie_additionalprimaryweapon_machine_clip_origin = (-1342, -1431, -361);
  291.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 28.8, 0);
  292.         break;
  293.     case "zombie_moon":
  294.         level.zombie_additionalprimaryweapon_machine_origin = (1480.8, 3450, -65);
  295.         level.zombie_additionalprimaryweapon_machine_angles = (0, 180, 0);
  296.         break;
  297.     case "zombie_cod5_prototype":
  298.         level.zombie_additionalprimaryweapon_machine_origin = (-160, -528, 1);
  299.         level.zombie_additionalprimaryweapon_machine_angles = (0, 0, 0);
  300.         level.zombie_additionalprimaryweapon_machine_clip_origin = (-162, -517, 17);
  301.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 0, 0);
  302.         break;
  303.     case "zombie_cod5_asylum":
  304.         level.zombie_additionalprimaryweapon_machine_origin = (-91, 540, 64);
  305.         level.zombie_additionalprimaryweapon_machine_angles = (0, 90, 0);
  306.         level.zombie_additionalprimaryweapon_machine_clip_origin = (-103, 540, 92);
  307.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 0, 0);
  308.         break;
  309.     case "zombie_cod5_sumpf":
  310.         level.zombie_additionalprimaryweapon_machine_origin = (9565, 327, -529);
  311.         level.zombie_additionalprimaryweapon_machine_angles = (0, 90, 0);
  312.         level.zombie_additionalprimaryweapon_machine_clip_origin = (9555, 327, -402);
  313.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 0, 0);
  314.         break;
  315.     case "zombie_cod5_factory":
  316.         level.zombie_additionalprimaryweapon_machine_origin = (-1089, -1366, 67);
  317.         level.zombie_additionalprimaryweapon_machine_angles = (0, 90, 0);
  318.         level.zombie_additionalprimaryweapon_machine_clip_origin = (-1100, -1365, 70);
  319.         level.zombie_additionalprimaryweapon_machine_clip_angles = (0, 0, 0);
  320.         break;
  321.     }
  322. }
  323.  
  324. /*------------------------------------
  325. chrisp - adding vo to track players ammo
  326. ------------------------------------*/
  327. track_players_ammo_count()
  328. {
  329.     self endon("disconnect");
  330.     self endon("death");
  331.    
  332.     wait(5);
  333.    
  334.     while(1)
  335.     {
  336.         players = get_players();
  337.         for(i=0;i<players.size;i++)
  338.         {
  339.             if(!IsDefined (players[i].player_ammo_low))
  340.             {
  341.                 players[i].player_ammo_low = 0;
  342.             }  
  343.             if(!IsDefined(players[i].player_ammo_out))
  344.             {
  345.                 players[i].player_ammo_out = 0;
  346.             }
  347.            
  348.             weap = players[i] getcurrentweapon();
  349.             //iprintln("current weapon: " + weap);
  350.             //iprintlnbold(weap);
  351.             //Excludes all Perk based 'weapons' so that you don't get low ammo spam.
  352.             if( !isDefined(weap) ||
  353.                     weap == "none" ||
  354.                     isSubStr( weap, "zombie_perk_bottle" ) ||
  355.                     is_placeable_mine( weap ) ||
  356.                     is_equipment( weap ) ||
  357.                     weap == "syrette_sp" ||
  358.                     weap == "zombie_knuckle_crack" ||
  359.                     weap == "zombie_bowie_flourish" ||
  360.                     weap == "zombie_sickle_flourish" ||
  361.                     issubstr( weap, "knife_ballistic_" ) ||
  362.                     ( GetSubStr( weap, 0, 3) == "gl_" ) ||
  363.                     weap == "humangun_zm" ||
  364.                     weap == "humangun_upgraded_zm" ||
  365.                     weap == "equip_gasmask_zm" ||
  366.                     weap == "lower_equip_gasmask_zm" )
  367.             {
  368.                 continue;
  369.             }
  370.             //iprintln("checking ammo for " + weap);
  371.             if ( players[i] GetAmmoCount( weap ) > 5)
  372.             {
  373.                 continue;
  374.             }      
  375.             if ( players[i] maps\_laststand::player_is_in_laststand() )
  376.             {              
  377.                 continue;
  378.             }
  379.             else if (players[i] GetAmmoCount( weap ) < 5 && players[i] GetAmmoCount( weap ) > 0)
  380.             {
  381.                 if (players[i].player_ammo_low != 1 )
  382.                 {
  383.                     players[i].player_ammo_low = 1;
  384.                     players[i] maps\_zombiemode_audio::create_and_play_dialog( "general", "ammo_low" );    
  385.                     players[i] thread ammo_dialog_timer();
  386.                 }
  387.    
  388.             }
  389.             else if (players[i] GetAmmoCount( weap ) == 0)
  390.             {  
  391.                 if(!isDefined(weap) || weap == "none")
  392.                 {
  393.                     continue;  
  394.                 }
  395.                 wait(2);
  396.                
  397.                 if( !isdefined( players[i] ) )
  398.                 {
  399.                     return;
  400.                 }
  401.                
  402.                 if( players[i] GetAmmoCount( weap ) != 0 )
  403.                 {
  404.                     continue;
  405.                 }
  406.                
  407.                 if( players[i].player_ammo_out != 1 )  
  408.                 {      
  409.                     players[i].player_ammo_out = 1;
  410.                     players[i] maps\_zombiemode_audio::create_and_play_dialog( "general", "ammo_out" );
  411.                     players[i] thread ammoout_dialog_timer();      
  412.                 }                                      
  413.             }
  414.             else
  415.             {
  416.                 continue;
  417.             }
  418.         }
  419.         wait(.5);
  420.     }  
  421. }
  422. ammo_dialog_timer()
  423. {
  424.     self endon("disconnect");
  425.     self endon("death");
  426.  
  427.     wait(20);
  428.     self.player_ammo_low = 0;          
  429. }
  430. ammoout_dialog_timer()
  431. {
  432.     self endon("disconnect");
  433.     self endon("death");
  434.  
  435.     wait(20);
  436.     self.player_ammo_out = 0;
  437. }
  438.  
  439. /*------------------------------------
  440. audio plays when more than 1 player connects
  441. ------------------------------------*/
  442. spawn_vo()
  443. {
  444.     //not sure if we need this
  445.     wait(1);
  446.    
  447.     players = getplayers();
  448.    
  449.     //just pick a random player for now and play some vo
  450.     if(players.size > 1)
  451.     {
  452.         player = random(players);
  453.         index = maps\_zombiemode_weapons::get_player_index(player);
  454.         player thread spawn_vo_player(index,players.size);
  455.     }
  456.  
  457. }
  458.  
  459. spawn_vo_player(index,num)
  460. {
  461.     sound = "plr_" + index + "_vox_" + num +"play";
  462.     self playsound(sound, "sound_done");           
  463.     self waittill("sound_done");
  464. }
  465.  
  466. testing_spawner_bug()
  467. {
  468.     wait( 0.1 );
  469.     level.round_number = 7;
  470.  
  471.     spawners = [];
  472.     spawners[0] = GetEnt( "testy", "targetname" );
  473.     while( 1 )
  474.     {
  475.         wait( 1 );
  476.         level.enemy_spawns = spawners;
  477.     }
  478. }
  479.  
  480. precache_shaders()
  481. {
  482.     PrecacheShader( "hud_chalk_1" );
  483.     PrecacheShader( "hud_chalk_2" );
  484.     PrecacheShader( "hud_chalk_3" );
  485.     PrecacheShader( "hud_chalk_4" );
  486.     PrecacheShader( "hud_chalk_5" );
  487.  
  488.     PrecacheShader( "zom_icon_community_pot" );
  489.     PrecacheShader( "zom_icon_community_pot_strip" );
  490.  
  491.     precacheshader("zom_icon_player_life");
  492. }
  493.  
  494. precache_models()
  495. {
  496.     precachemodel( "char_ger_zombieeye" );
  497.     precachemodel( "p_zom_win_bars_01_vert04_bend_180" );
  498.     precachemodel( "p_zom_win_bars_01_vert01_bend_180" );
  499.     precachemodel( "p_zom_win_bars_01_vert04_bend" );
  500.     precachemodel( "p_zom_win_bars_01_vert01_bend" );
  501.     PreCacheModel( "p_zom_win_cell_bars_01_vert04_bent" );
  502.     precachemodel( "p_zom_win_cell_bars_01_vert01_bent" );
  503.     PrecacheModel( "tag_origin" );
  504.  
  505.     // Counter models
  506.     PrecacheModel( "p_zom_counter_0" );
  507.     PrecacheModel( "p_zom_counter_1" );
  508.     PrecacheModel( "p_zom_counter_2" );
  509.     PrecacheModel( "p_zom_counter_3" );
  510.     PrecacheModel( "p_zom_counter_4" );
  511.     PrecacheModel( "p_zom_counter_5" );
  512.     PrecacheModel( "p_zom_counter_6" );
  513.     PrecacheModel( "p_zom_counter_7" );
  514.     PrecacheModel( "p_zom_counter_8" );
  515.     PrecacheModel( "p_zom_counter_9" );
  516.  
  517.     //  Player Tombstone
  518.     precachemodel("zombie_revive");
  519.  
  520.     PrecacheModel( "zombie_z_money_icon" );
  521. }
  522.  
  523. init_shellshocks()
  524. {
  525.     level.player_killed_shellshock = "zombie_death";
  526.     PrecacheShellshock( level.player_killed_shellshock );
  527. }
  528.  
  529. init_strings()
  530. {
  531.     PrecacheString( &"ZOMBIE_WEAPONCOSTAMMO" );
  532.     PrecacheString( &"ZOMBIE_ROUND" );
  533.     PrecacheString( &"SCRIPT_PLUS" );
  534.     PrecacheString( &"ZOMBIE_GAME_OVER" );
  535.     PrecacheString( &"ZOMBIE_SURVIVED_ROUND" );
  536.     PrecacheString( &"ZOMBIE_SURVIVED_ROUNDS" );
  537.     PrecacheString( &"ZOMBIE_SURVIVED_NOMANS" );
  538.     PrecacheString( &"ZOMBIE_EXTRA_LIFE" );
  539.  
  540.     add_zombie_hint( "undefined", &"ZOMBIE_UNDEFINED" );
  541.  
  542.     // Random Treasure Chest
  543.     add_zombie_hint( "default_treasure_chest_950", &"ZOMBIE_RANDOM_WEAPON_950" );
  544.  
  545.     // Barrier Pieces
  546.     add_zombie_hint( "default_buy_barrier_piece_10", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_10" );
  547.     add_zombie_hint( "default_buy_barrier_piece_20", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_20" );
  548.     add_zombie_hint( "default_buy_barrier_piece_50", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_50" );
  549.     add_zombie_hint( "default_buy_barrier_piece_100", &"ZOMBIE_BUTTON_BUY_BACK_BARRIER_100" );
  550.  
  551.     // REWARD Barrier Pieces
  552.     add_zombie_hint( "default_reward_barrier_piece", &"ZOMBIE_BUTTON_REWARD_BARRIER" );
  553.     add_zombie_hint( "default_reward_barrier_piece_10", &"ZOMBIE_BUTTON_REWARD_BARRIER_10" );
  554.     add_zombie_hint( "default_reward_barrier_piece_20", &"ZOMBIE_BUTTON_REWARD_BARRIER_20" );
  555.     add_zombie_hint( "default_reward_barrier_piece_30", &"ZOMBIE_BUTTON_REWARD_BARRIER_30" );
  556.     add_zombie_hint( "default_reward_barrier_piece_40", &"ZOMBIE_BUTTON_REWARD_BARRIER_40" );
  557.     add_zombie_hint( "default_reward_barrier_piece_50", &"ZOMBIE_BUTTON_REWARD_BARRIER_50" );
  558.  
  559.     // Debris
  560.     add_zombie_hint( "default_buy_debris_100", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_100" );
  561.     add_zombie_hint( "default_buy_debris_200", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_200" );
  562.     add_zombie_hint( "default_buy_debris_250", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_250" );
  563.     add_zombie_hint( "default_buy_debris_500", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_500" );
  564.     add_zombie_hint( "default_buy_debris_750", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_750" );
  565.     add_zombie_hint( "default_buy_debris_1000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1000" );
  566.     add_zombie_hint( "default_buy_debris_1250", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1250" );
  567.     add_zombie_hint( "default_buy_debris_1500", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1500" );
  568.     add_zombie_hint( "default_buy_debris_1750", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_1750" );
  569.     add_zombie_hint( "default_buy_debris_2000", &"ZOMBIE_BUTTON_BUY_CLEAR_DEBRIS_2000" );
  570.  
  571.     // Doors
  572.     add_zombie_hint( "default_buy_door_100", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_100" );
  573.     add_zombie_hint( "default_buy_door_200", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_200" );
  574.     add_zombie_hint( "default_buy_door_250", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_250" );
  575.     add_zombie_hint( "default_buy_door_500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_500" );
  576.     add_zombie_hint( "default_buy_door_750", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_750" );
  577.     add_zombie_hint( "default_buy_door_1000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1000" );
  578.     add_zombie_hint( "default_buy_door_1250", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1250" );
  579.     add_zombie_hint( "default_buy_door_1500", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1500" );
  580.     add_zombie_hint( "default_buy_door_1750", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_1750" );
  581.     add_zombie_hint( "default_buy_door_2000", &"ZOMBIE_BUTTON_BUY_OPEN_DOOR_2000" );
  582.  
  583.     // Areas
  584.     add_zombie_hint( "default_buy_area_100", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_100" );
  585.     add_zombie_hint( "default_buy_area_200", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_200" );
  586.     add_zombie_hint( "default_buy_area_250", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_250" );
  587.     add_zombie_hint( "default_buy_area_500", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_500" );
  588.     add_zombie_hint( "default_buy_area_750", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_750" );
  589.     add_zombie_hint( "default_buy_area_1000", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1000" );
  590.     add_zombie_hint( "default_buy_area_1250", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1250" );
  591.     add_zombie_hint( "default_buy_area_1500", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1500" );
  592.     add_zombie_hint( "default_buy_area_1750", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_1750" );
  593.     add_zombie_hint( "default_buy_area_2000", &"ZOMBIE_BUTTON_BUY_OPEN_AREA_2000" );
  594.  
  595.     // POWER UPS
  596.     add_zombie_hint( "powerup_fire_sale_cost", &"ZOMBIE_FIRE_SALE_COST" );
  597.  
  598. }
  599.  
  600. init_sounds()
  601. {
  602.     add_sound( "end_of_round", "mus_zmb_round_over" );
  603.     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.
  604.     add_sound( "chalk_one_up", "mus_zmb_chalk" );
  605.     add_sound( "purchase", "zmb_cha_ching" );
  606.     add_sound( "no_purchase", "zmb_no_cha_ching" );
  607.  
  608.     // Zombification
  609.     // TODO need to vary these up
  610.     add_sound( "playerzombie_usebutton_sound", "zmb_zombie_vocals_attack" );
  611.     add_sound( "playerzombie_attackbutton_sound", "zmb_zombie_vocals_attack" );
  612.     add_sound( "playerzombie_adsbutton_sound", "zmb_zombie_vocals_attack" );
  613.  
  614.     // Head gib
  615.     add_sound( "zombie_head_gib", "zmb_zombie_head_gib" );
  616.  
  617.     // Blockers
  618.     add_sound( "rebuild_barrier_piece", "zmb_repair_boards" );
  619.     add_sound( "rebuild_barrier_metal_piece", "zmb_metal_repair" );
  620.     add_sound( "rebuild_barrier_hover", "zmb_boards_float" );
  621.     add_sound( "debris_hover_loop", "zmb_couch_loop" );
  622.     add_sound( "break_barrier_piece", "zmb_break_boards" );
  623.     add_sound( "grab_metal_bar", "zmb_bar_pull" );
  624.     add_sound( "break_metal_bar", "zmb_bar_break" );
  625.     add_sound( "drop_metal_bar", "zmb_bar_drop" );
  626.     add_sound("blocker_end_move", "zmb_board_slam");
  627.     add_sound( "barrier_rebuild_slam", "zmb_board_slam" );
  628.     add_sound( "bar_rebuild_slam", "zmb_bar_repair" );
  629.     add_sound( "zmb_rock_fix", "zmb_break_rock_barrier_fix" );
  630.     add_sound( "zmb_vent_fix", "evt_vent_slat_repair" );
  631.  
  632.     // Doors
  633.     add_sound( "door_slide_open", "zmb_door_slide_open" );
  634.     add_sound( "door_rotate_open", "zmb_door_slide_open" );
  635.  
  636.     // Debris
  637.     add_sound( "debris_move", "zmb_weap_wall" );
  638.  
  639.     // Random Weapon Chest
  640.     add_sound( "open_chest", "zmb_lid_open" );
  641.     add_sound( "music_chest", "zmb_music_box" );
  642.     add_sound( "close_chest", "zmb_lid_close" );
  643.  
  644.     // Weapons on walls
  645.     add_sound( "weapon_show", "zmb_weap_wall" );
  646.  
  647. }
  648.  
  649. init_levelvars()
  650. {
  651.     // Variables
  652.     // used to a check in last stand for players to become zombies
  653.     level.is_zombie_level           = true;
  654.     level.laststandpistol           = "m1911_zm";       // so we dont get the uber colt when we're knocked out
  655.     level.first_round               = true;
  656.     level.round_number              = 1;
  657.     level.round_start_time          = 0;
  658.     level.pro_tips_start_time       = 0;
  659.     level.intermission              = false;
  660.     level.dog_intermission          = false;
  661.     level.zombie_total              = 0;
  662.     level.total_zombies_killed      = 0;
  663.     level.no_laststandmissionfail   = true;
  664.     level.hudelem_count             = 0;
  665.     level.zombie_move_speed         = 1;
  666.     level.enemy_spawns              = [];               // List of normal zombie spawners
  667.     level.zombie_rise_spawners      = [];               // List of zombie riser locations
  668. //  level.crawlers_enabled          = 1;
  669.  
  670.     // Used for kill counters
  671.     level.counter_model[0] = "p_zom_counter_0";
  672.     level.counter_model[1] = "p_zom_counter_1";
  673.     level.counter_model[2] = "p_zom_counter_2";
  674.     level.counter_model[3] = "p_zom_counter_3";
  675.     level.counter_model[4] = "p_zom_counter_4";
  676.     level.counter_model[5] = "p_zom_counter_5";
  677.     level.counter_model[6] = "p_zom_counter_6";
  678.     level.counter_model[7] = "p_zom_counter_7";
  679.     level.counter_model[8] = "p_zom_counter_8";
  680.     level.counter_model[9] = "p_zom_counter_9";
  681.  
  682.     level.zombie_vars = [];
  683.  
  684.     difficulty = 1;
  685.     column = int(difficulty) + 1;
  686.  
  687.     //#######################################################################
  688.     // NOTE:  These values are in mp/zombiemode.csv and will override
  689.     //  whatever you put in as a value below.  However, if they don't exist
  690.     //  in the file, then the values below will be used.
  691.     //#######################################################################
  692.     //  set_zombie_var( identifier,                     value,  float,  column );
  693.  
  694.     // AI
  695.     set_zombie_var( "zombie_health_increase",           100,    false,  column );   //  cumulatively add this to the zombies' starting health each round (up to round 10)
  696.     set_zombie_var( "zombie_health_increase_multiplier",0.1,    true,   column );   //  after round 10 multiply the zombies' starting health by this amount
  697.     set_zombie_var( "zombie_health_start",              150,    false,  column );   //  starting health of a zombie at round 1
  698.     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.
  699.     set_zombie_var( "zombie_new_runner_interval",        10,    false,  column );   //  Interval between changing walkers who are too far away into runners
  700.     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
  701.  
  702.     set_zombie_var( "zombie_max_ai",                    24,     false,  column );   //  Base number of zombies per player (modified by round #)
  703.     set_zombie_var( "zombie_ai_per_player",             6,      false,  column );   //  additional zombie modifier for each player in the game
  704.     set_zombie_var( "below_world_check",                -1000 );                    //  Check height to see if a zombie has fallen through the world.
  705.  
  706.     // Round   
  707.     set_zombie_var( "spectators_respawn",               true );     // Respawn in the spectators in between rounds
  708.     set_zombie_var( "zombie_use_failsafe",              true );     // Will slowly kill zombies who are stuck
  709.     set_zombie_var( "zombie_between_round_time",        10 );       // How long to pause after the round ends
  710.     set_zombie_var( "zombie_intermission_time",         15 );       // Length of time to show the end of game stats
  711.     set_zombie_var( "game_start_delay",                 0,      false,  column );   // How much time to give people a break before starting spawning
  712.  
  713.     // Life and death
  714.     set_zombie_var( "penalty_no_revive",                0.10,   true,   column );   // Percentage of money you lose if you let a teammate die
  715.     set_zombie_var( "penalty_died",                     0.0,    true,   column );   // Percentage of money lost if you die
  716.     set_zombie_var( "penalty_downed",                   0.05,   true,   column );   // Percentage of money lost if you go down // ww: told to remove downed point loss
  717.     set_zombie_var( "starting_lives",                   1,      false,  column );   // How many lives a solo player starts out with
  718.  
  719.     players = get_players();
  720.     points = set_zombie_var( ("zombie_score_start_"+players.size+"p"), 3000, false, column );
  721.     points = set_zombie_var( ("zombie_score_start_"+players.size+"p"), 3000, false, column );
  722.  
  723.  
  724.     set_zombie_var( "zombie_score_kill_4player",        50 );       // Individual Points for a zombie kill in a 4 player game
  725.     set_zombie_var( "zombie_score_kill_3player",        50 );       // Individual Points for a zombie kill in a 3 player game
  726.     set_zombie_var( "zombie_score_kill_2player",        50 );       // Individual Points for a zombie kill in a 2 player game
  727.     set_zombie_var( "zombie_score_kill_1player",        50 );       // Individual Points for a zombie kill in a 1 player game
  728.  
  729.     set_zombie_var( "zombie_score_kill_4p_team",        30 );       // Team Points for a zombie kill in a 4 player game
  730.     set_zombie_var( "zombie_score_kill_3p_team",        35 );       // Team Points for a zombie kill in a 3 player game
  731.     set_zombie_var( "zombie_score_kill_2p_team",        45 );       // Team Points for a zombie kill in a 2 player game
  732.     set_zombie_var( "zombie_score_kill_1p_team",         0 );       // Team Points for a zombie kill in a 1 player game
  733.  
  734.     set_zombie_var( "zombie_score_damage_normal",       10 );       // points gained for a hit with a non-automatic weapon
  735.     set_zombie_var( "zombie_score_damage_light",        10 );       // points gained for a hit with an automatic weapon
  736.  
  737.     set_zombie_var( "zombie_score_bonus_melee",         80 );       // Bonus points for a melee kill
  738.     set_zombie_var( "zombie_score_bonus_head",          50 );       // Bonus points for a head shot kill
  739.     set_zombie_var( "zombie_score_bonus_neck",          20 );       // Bonus points for a neck shot kill
  740.     set_zombie_var( "zombie_score_bonus_torso",         10 );       // Bonus points for a torso shot kill
  741.     set_zombie_var( "zombie_score_bonus_burn",          10 );       // Bonus points for a burn kill
  742.  
  743.     set_zombie_var( "zombie_flame_dmg_point_delay",     500 ); 
  744.  
  745.     set_zombie_var( "zombify_player",                   false );    // Default to not zombify the player till further support
  746.  
  747.     if ( IsSplitScreen() )
  748.     {
  749.         set_zombie_var( "zombie_timer_offset",          280 );  // hud offsets
  750.     }
  751. }
  752.  
  753. init_dvars()
  754. {
  755.     setSavedDvar( "fire_world_damage", "0" );  
  756.     setSavedDvar( "fire_world_damage_rate", "0" ); 
  757.     setSavedDvar( "fire_world_damage_duration", "0" ); 
  758.  
  759.     if( GetDvar( #"zombie_debug" ) == "" )
  760.     {
  761.         SetDvar( "zombie_debug", "0" );
  762.     }
  763.  
  764.     if( GetDvar( #"zombie_cheat" ) == "" )
  765.     {
  766.         SetDvar( "zombie_cheat", "0" );
  767.     }
  768.    
  769.     if ( level.script != "zombie_cod5_prototype" )
  770.     {
  771.         SetDvar( "magic_chest_movable", "1" );
  772.     }
  773.  
  774.     if(GetDvar( #"magic_box_explore_only") == "")
  775.     {
  776.         SetDvar( "magic_box_explore_only", "1" );
  777.     }
  778.  
  779.     SetDvar( "revive_trigger_radius", "75" );
  780.     SetDvar( "player_lastStandBleedoutTime", "45" );
  781.  
  782.     SetDvar( "scr_deleteexplosivesonspawn", "0" );
  783.  
  784.     // HACK: To avoid IK crash in zombiemode: MikeA 9/18/2009  
  785.     //setDvar( "ik_enable", "0" );
  786. }
  787.  
  788.  
  789. init_mutators()
  790. {
  791.     level.mutators = [];
  792.  
  793.     init_mutator( "mutator_noPerks" );
  794.     init_mutator( "mutator_noTraps" );
  795.     init_mutator( "mutator_noMagicBox" );
  796.     init_mutator( "mutator_noRevive" );
  797.     init_mutator( "mutator_noPowerups" );
  798.     init_mutator( "mutator_noReloads" );
  799.     init_mutator( "mutator_noBoards" );
  800.     init_mutator( "mutator_fogMatch" );
  801.     init_mutator( "mutator_quickStart" );
  802.     init_mutator( "mutator_headshotsOnly" );
  803.     init_mutator( "mutator_friendlyFire" );
  804.     init_mutator( "mutator_doubleMoney" );
  805.     init_mutator( "mutator_susceptible" );
  806.     init_mutator( "mutator_powerShot" );
  807. }
  808.  
  809. init_mutator( mutator_s )
  810. {
  811.     level.mutators[ mutator_s ] = ( "1" == GetDvar( mutator_s ) );
  812. }
  813.  
  814.  
  815. init_function_overrides()
  816. {
  817.     // Function pointers
  818.     level.custom_introscreen        = ::zombie_intro_screen;
  819.     level.custom_intermission       = ::player_intermission;
  820.     level.reset_clientdvars         = ::onPlayerConnect_clientDvars;
  821.     // Sets up function pointers for animscripts to refer to
  822.     level.playerlaststand_func      = ::player_laststand;
  823.     //  level.global_kill_func      = maps\_zombiemode_spawner::zombie_death;
  824.     level.global_damage_func        = maps\_zombiemode_spawner::zombie_damage;
  825.     level.global_damage_func_ads    = maps\_zombiemode_spawner::zombie_damage_ads;
  826.     level.overridePlayerKilled      = ::player_killed_override;
  827.     level.overridePlayerDamage      = ::player_damage_override; //_cheat;
  828.     level.overrideActorKilled       = ::actor_killed_override;
  829.     level.overrideActorDamage       = ::actor_damage_override;
  830.     level.melee_miss_func           = ::zombiemode_melee_miss;
  831.     level.player_becomes_zombie     = ::zombify_player;
  832.     level.is_friendly_fire_on       = ::is_friendly_fire_on;
  833.     level.can_revive                = ::can_revive;
  834.     level.zombie_last_stand         = ::last_stand_pistol_swap;
  835.     level.zombie_last_stand_pistol_memory = ::last_stand_save_pistol_ammo;
  836.     level.zombie_last_stand_ammo_return     = ::last_stand_restore_pistol_ammo;
  837.     level.prevent_player_damage     = ::player_prevent_damage;
  838.  
  839.     if( !IsDefined( level.Player_Spawn_func ) )
  840.     {
  841.         level.Player_Spawn_func = ::coop_player_spawn_placement;
  842.     }
  843. }
  844.  
  845.  
  846. // for zombietron, see maps\_zombietron_main::initZombieLeaderboardData()
  847. //
  848. initZombieLeaderboardData()
  849. {
  850.     // Initializing Leaderboard Stat Variables -- string values match stats.ddl
  851.     level.zombieLeaderboardStatVariable["zombie_theater"]["highestwave"] = "zombie_theater_highestwave";
  852.     level.zombieLeaderboardStatVariable["zombie_theater"]["timeinwave"]  = "zombie_theater_timeinwave";
  853.     level.zombieLeaderboardStatVariable["zombie_theater"]["totalpoints"] = "zombie_theater_totalpoints";
  854.  
  855.     level.zombieLeaderboardStatVariable["zombie_pentagon"]["highestwave"] = "zombie_pentagon_highestwave";
  856.     level.zombieLeaderboardStatVariable["zombie_pentagon"]["timeinwave"]  = "zombie_pentagon_timeinwave";
  857.     level.zombieLeaderboardStatVariable["zombie_pentagon"]["totalpoints"] = "zombie_pentagon_totalpoints";
  858.  
  859.     // DLC 1 Cod 5 Zombies Leaderboard Stats
  860.  
  861.     level.zombieLeaderboardStatVariable["zombie_cod5_asylum"]["highestwave"] = "zombie_asylum_highestwave";
  862.     level.zombieLeaderboardStatVariable["zombie_cod5_asylum"]["timeinwave"]  = "zombie_asylum_timeinwave";
  863.     level.zombieLeaderboardStatVariable["zombie_cod5_asylum"]["totalpoints"] = "zombie_asylum_totalpoints";
  864.  
  865.     level.zombieLeaderboardStatVariable["zombie_cod5_factory"]["highestwave"] = "zombie_factory_highestwave";
  866.     level.zombieLeaderboardStatVariable["zombie_cod5_factory"]["timeinwave"]  = "zombie_factory_timeinwave";
  867.     level.zombieLeaderboardStatVariable["zombie_cod5_factory"]["totalpoints"] = "zombie_factory_totalpoints";
  868.  
  869.     level.zombieLeaderboardStatVariable["zombie_cod5_prototype"]["highestwave"] = "zombie_prototype_highestwave";
  870.     level.zombieLeaderboardStatVariable["zombie_cod5_prototype"]["timeinwave"]  = "zombie_prototype_timeinwave";
  871.     level.zombieLeaderboardStatVariable["zombie_cod5_prototype"]["totalpoints"] = "zombie_prototype_totalpoints";
  872.  
  873.     level.zombieLeaderboardStatVariable["zombie_cod5_sumpf"]["highestwave"] = "zombie_sumpf_highestwave";
  874.     level.zombieLeaderboardStatVariable["zombie_cod5_sumpf"]["timeinwave"]  = "zombie_sumpf_timeinwave";
  875.     level.zombieLeaderboardStatVariable["zombie_cod5_sumpf"]["totalpoints"] = "zombie_sumpf_totalpoints";
  876.    
  877.     // DLC 2 Zombies Leaderboard Stats
  878.    
  879.     level.zombieLeaderboardStatVariable["zombie_cosmodrome"]["highestwave"] = "zombie_cosmodrome_highestwave";
  880.     level.zombieLeaderboardStatVariable["zombie_cosmodrome"]["timeinwave"]  = "zombie_cosmodrome_timeinwave";
  881.     level.zombieLeaderboardStatVariable["zombie_cosmodrome"]["totalpoints"] = "zombie_cosmodrome_totalpoints";
  882.  
  883.     // DLC 3 Zombies Leaderboard Stats
  884.    
  885.     level.zombieLeaderboardStatVariable["zombie_coast"]["highestwave"] = "zombie_coast_highestwave";
  886.     level.zombieLeaderboardStatVariable["zombie_coast"]["timeinwave"]  = "zombie_coast_timeinwave";
  887.     level.zombieLeaderboardStatVariable["zombie_coast"]["totalpoints"] = "zombie_coast_totalpoints";
  888.  
  889.     // DLC 4 Zombies Leaderboard Stats
  890.    
  891.     level.zombieLeaderboardStatVariable["zombie_temple"]["highestwave"] = "zombie_temple_highestwave";
  892.     level.zombieLeaderboardStatVariable["zombie_temple"]["timeinwave"]  = "zombie_temple_timeinwave";
  893.     level.zombieLeaderboardStatVariable["zombie_temple"]["totalpoints"] = "zombie_temple_totalpoints";
  894.  
  895.     // DLC 5 Zombies Leaderboard Stats
  896.    
  897.     level.zombieLeaderboardStatVariable["zombie_moon"]["highestwave"] = "zombie_moon_highestwave";
  898.     level.zombieLeaderboardStatVariable["zombie_moon"]["timeinwave"]  = "zombie_moon_timeinwave";
  899.     level.zombieLeaderboardStatVariable["zombie_moon"]["totalpoints"] = "zombie_moon_totalpoints";
  900.     level.zombieLeaderboardStatVariable["zombie_moon"]["nomanslandtime"] = "zombie_moon_nomansland";
  901.  
  902.  
  903.     // Initializing Leaderboard Number.  Matches values in live_leaderboard.h.
  904.     level.zombieLeaderboardNumber["zombie_theater"]["waves"] = 0;
  905.     level.zombieLeaderboardNumber["zombie_theater"]["points"] = 1;
  906.  
  907.     // level.zombieLeaderboardNumber["zombietron"]["waves"] = 3;  // defined in _zombietron_main.gsc
  908.     // level.zombieLeaderboardNumber["zombietron"]["points"] = 4; // defined in _zombietron_main.gsc
  909.  
  910.     level.zombieLeaderboardNumber["zombie_pentagon"]["waves"] = 6;
  911.     level.zombieLeaderboardNumber["zombie_pentagon"]["points"] = 7;
  912.  
  913.     // DLC 1 Cod 5 Zombie leaderboards
  914.  
  915.     // Asylum
  916.     level.zombieLeaderboardNumber["zombie_cod5_asylum"]["waves"] = 9;
  917.     level.zombieLeaderboardNumber["zombie_cod5_asylum"]["points"] = 10;
  918.  
  919.     // Factory
  920.     level.zombieLeaderboardNumber["zombie_cod5_factory"]["waves"] = 12;
  921.     level.zombieLeaderboardNumber["zombie_cod5_factory"]["points"] = 13;
  922.  
  923.     // Prototype
  924.     level.zombieLeaderboardNumber["zombie_cod5_prototype"]["waves"] = 15;
  925.     level.zombieLeaderboardNumber["zombie_cod5_prototype"]["points"] = 16;
  926.  
  927.     // Sumpf
  928.     level.zombieLeaderboardNumber["zombie_cod5_sumpf"]["waves"] = 18;
  929.     level.zombieLeaderboardNumber["zombie_cod5_sumpf"]["points"] = 19;
  930.  
  931.     // DLC 2 Zombie leaderboards
  932.    
  933.     // Cosmodrome
  934.     level.zombieLeaderboardNumber["zombie_cosmodrome"]["waves"] = 21;
  935.     level.zombieLeaderboardNumber["zombie_cosmodrome"]["points"] = 22;
  936.  
  937.     // DLC 3 Zombie leaderboards
  938.    
  939.     // Coast
  940.     level.zombieLeaderboardNumber["zombie_coast"]["waves"] = 24;
  941.     level.zombieLeaderboardNumber["zombie_coast"]["points"] = 25;
  942.  
  943.     // DLC 4 Zombie leaderboards
  944.    
  945.     // Temple
  946.     level.zombieLeaderboardNumber["zombie_temple"]["waves"] = 27;
  947.     level.zombieLeaderboardNumber["zombie_temple"]["points"] = 28;
  948.    
  949.     // DLC 5 Zombie leaderboards
  950.    
  951.     // Moon
  952.     level.zombieLeaderboardNumber["zombie_moon"]["waves"] = 30;
  953.     level.zombieLeaderboardNumber["zombie_moon"]["points"] = 31;
  954.     level.zombieLeaderboardNumber["zombie_moon"]["kills"] = 32;
  955. }
  956.  
  957.  
  958. init_flags()
  959. {
  960.     flag_init( "spawn_point_override" );
  961.     flag_init( "power_on" );
  962.     flag_init( "crawler_round" );
  963.     flag_init( "spawn_zombies", true );
  964.     flag_init( "dog_round" );
  965.     flag_init( "begin_spawning" );
  966.     flag_init( "end_round_wait" );
  967.     flag_init( "wait_and_revive" );
  968.     flag_init("instant_revive");   
  969. }
  970.  
  971. // Client flags registered here should be for global zombie systems, and should
  972. // prefer to use high flag numbers and work downwards.
  973.  
  974. // Level specific flags should be registered in the level, and should prefer
  975. // low numbers, and work upwards.
  976.  
  977. // Ensure that this function and the function in _zombiemode.csc match.
  978.  
  979. init_client_flags()
  980. {
  981.     // Client flags for script movers
  982.    
  983.     level._ZOMBIE_SCRIPTMOVER_FLAG_BOX_RANDOM   = 15;
  984.    
  985.    
  986.     if(is_true(level.use_clientside_board_fx))
  987.     {
  988.         //for tearing down and repairing the boards and rock chunks
  989.         level._ZOMBIE_SCRIPTMOVER_FLAG_BOARD_HORIZONTAL_FX  = 14;
  990.         level._ZOMBIE_SCRIPTMOVER_FLAG_BOARD_VERTICAL_FX    = 13;
  991.     }
  992.     if(is_true(level.use_clientside_rock_tearin_fx))
  993.     {
  994.         level._ZOMBIE_SCRIPTMOVER_FLAG_ROCK_FX  = 12;  
  995.     }
  996.    
  997.     // Client flags for the player
  998.    
  999.     level._ZOMBIE_PLAYER_FLAG_CLOAK_WEAPON = 14;
  1000.     level._ZOMBIE_PLAYER_FLAG_DIVE2NUKE_VISION = 13;
  1001.     level._ZOMBIE_PLAYER_FLAG_DEADSHOT_PERK = 12;
  1002.  
  1003.     if(is_true(level.riser_fx_on_client))
  1004.     {
  1005.         level._ZOMBIE_ACTOR_ZOMBIE_RISER_FX = 8;
  1006.         if(!isDefined(level._no_water_risers))
  1007.         {
  1008.             level._ZOMBIE_ACTOR_ZOMBIE_RISER_FX_WATER = 9;     
  1009.         }
  1010.         if(is_true(level.risers_use_low_gravity_fx))
  1011.         {
  1012.             level._ZOMBIE_ACTOR_ZOMBIE_RISER_LOWG_FX = 7;
  1013.         }
  1014.     }
  1015.    
  1016. }
  1017.  
  1018. init_fx()
  1019. {
  1020.     level._effect["wood_chunk_destory"]         = LoadFX( "impacts/fx_large_woodhit" );
  1021.     level._effect["fx_zombie_bar_break"]        = LoadFX( "maps/zombie/fx_zombie_bar_break" );
  1022.     level._effect["fx_zombie_bar_break_lite"]   = LoadFX( "maps/zombie/fx_zombie_bar_break_lite" );
  1023.    
  1024.     level._effect["edge_fog"]                   = LoadFX( "maps/zombie/fx_fog_zombie_amb" );
  1025.     level._effect["chest_light"]                = LoadFX( "env/light/fx_ray_sun_sm_short" );
  1026.  
  1027.     level._effect["eye_glow"]                   = LoadFX( "misc/fx_zombie_eye_single" );
  1028.  
  1029.     level._effect["headshot"]                   = LoadFX( "impacts/fx_flesh_hit" );
  1030.     level._effect["headshot_nochunks"]          = LoadFX( "misc/fx_zombie_bloodsplat" );
  1031.     level._effect["bloodspurt"]                 = LoadFX( "misc/fx_zombie_bloodspurt" );
  1032.     level._effect["tesla_head_light"]           = LoadFX( "maps/zombie/fx_zombie_tesla_neck_spurt");
  1033.  
  1034.     level._effect["rise_burst_water"]           = LoadFX("maps/zombie/fx_zombie_body_wtr_burst");
  1035.     level._effect["rise_billow_water"]          = LoadFX("maps/zombie/fx_zombie_body_wtr_billowing");
  1036.     level._effect["rise_dust_water"]            = LoadFX("maps/zombie/fx_zombie_body_wtr_falling");
  1037.  
  1038.     level._effect["rise_burst"]                 = LoadFX("maps/zombie/fx_mp_zombie_hand_dirt_burst");
  1039.     level._effect["rise_billow"]                = LoadFX("maps/zombie/fx_mp_zombie_body_dirt_billowing");
  1040.     level._effect["rise_dust"]                  = LoadFX("maps/zombie/fx_mp_zombie_body_dust_falling");
  1041.  
  1042.     level._effect["fall_burst"]                 = LoadFX("maps/zombie/fx_mp_zombie_hand_dirt_burst");
  1043.     level._effect["fall_billow"]                = LoadFX("maps/zombie/fx_mp_zombie_body_dirt_billowing");
  1044.     level._effect["fall_dust"]                  = LoadFX("maps/zombie/fx_mp_zombie_body_dust_falling");
  1045.  
  1046.     // Flamethrower
  1047.     level._effect["character_fire_pain_sm"]     = LoadFX( "env/fire/fx_fire_player_sm_1sec" );
  1048.     level._effect["character_fire_death_sm"]    = LoadFX( "env/fire/fx_fire_player_md" );
  1049.     level._effect["character_fire_death_torso"] = LoadFX( "env/fire/fx_fire_player_torso" );
  1050.  
  1051.     level._effect["def_explosion"]              = LoadFX("explosions/fx_default_explosion");
  1052.     level._effect["betty_explode"]              = LoadFX("weapon/bouncing_betty/fx_explosion_betty_generic");
  1053. }
  1054.  
  1055.  
  1056. // zombie specific anims
  1057. init_standard_zombie_anims()
  1058. {
  1059.     // deaths
  1060.     level.scr_anim["zombie"]["death1"]  = %ai_zombie_death_v1;
  1061.     level.scr_anim["zombie"]["death2"]  = %ai_zombie_death_v2;
  1062.     level.scr_anim["zombie"]["death3"]  = %ai_zombie_crawl_death_v1;
  1063.     level.scr_anim["zombie"]["death4"]  = %ai_zombie_crawl_death_v2;
  1064.  
  1065.     // run cycles
  1066.    
  1067.     level.scr_anim["zombie"]["walk1"]   = %ai_zombie_walk_v1;
  1068.     level.scr_anim["zombie"]["walk2"]   = %ai_zombie_walk_v2;
  1069.     level.scr_anim["zombie"]["walk3"]   = %ai_zombie_walk_v3;
  1070.     level.scr_anim["zombie"]["walk4"]   = %ai_zombie_walk_v4;
  1071.     level.scr_anim["zombie"]["walk5"]   = %ai_zombie_walk_v6;
  1072.     level.scr_anim["zombie"]["walk6"]   = %ai_zombie_walk_v7;
  1073.     level.scr_anim["zombie"]["walk7"]   = %ai_zombie_walk_v9;   //was goose step walk - overridden in theatre only (v8)
  1074.     level.scr_anim["zombie"]["walk8"]   = %ai_zombie_walk_v9;
  1075.  
  1076.     level.scr_anim["zombie"]["run1"]    = %ai_zombie_walk_fast_v1;
  1077.     level.scr_anim["zombie"]["run2"]    = %ai_zombie_walk_fast_v2;
  1078.     level.scr_anim["zombie"]["run3"]    = %ai_zombie_walk_fast_v3;
  1079.     level.scr_anim["zombie"]["run4"]    = %ai_zombie_run_v2;
  1080.     level.scr_anim["zombie"]["run5"]    = %ai_zombie_run_v4;
  1081.     level.scr_anim["zombie"]["run6"]    = %ai_zombie_run_v3;
  1082.     //level.scr_anim["zombie"]["run4"]  = %ai_zombie_run_v1;
  1083.     //level.scr_anim["zombie"]["run6"]  = %ai_zombie_run_v4;
  1084.  
  1085.     level.scr_anim["zombie"]["sprint1"] = %ai_zombie_sprint_v1;
  1086.     level.scr_anim["zombie"]["sprint2"] = %ai_zombie_sprint_v2;
  1087.     level.scr_anim["zombie"]["sprint3"] = %ai_zombie_sprint_v1;
  1088.     level.scr_anim["zombie"]["sprint4"] = %ai_zombie_sprint_v2;
  1089.     //level.scr_anim["zombie"]["sprint3"] = %ai_zombie_sprint_v3;
  1090.     //level.scr_anim["zombie"]["sprint3"] = %ai_zombie_sprint_v4;
  1091.     //level.scr_anim["zombie"]["sprint4"] = %ai_zombie_sprint_v5;
  1092.  
  1093.     // run cycles in prone
  1094.     level.scr_anim["zombie"]["crawl1"]  = %ai_zombie_crawl;
  1095.     level.scr_anim["zombie"]["crawl2"]  = %ai_zombie_crawl_v1;
  1096.     level.scr_anim["zombie"]["crawl3"]  = %ai_zombie_crawl_v2;
  1097.     level.scr_anim["zombie"]["crawl4"]  = %ai_zombie_crawl_v3;
  1098.     level.scr_anim["zombie"]["crawl5"]  = %ai_zombie_crawl_v4;
  1099.     level.scr_anim["zombie"]["crawl6"]  = %ai_zombie_crawl_v5;
  1100.     level.scr_anim["zombie"]["crawl_hand_1"] = %ai_zombie_walk_on_hands_a;
  1101.     level.scr_anim["zombie"]["crawl_hand_2"] = %ai_zombie_walk_on_hands_b;
  1102.  
  1103.     level.scr_anim["zombie"]["crawl_sprint1"]   = %ai_zombie_crawl_sprint;
  1104.     level.scr_anim["zombie"]["crawl_sprint2"]   = %ai_zombie_crawl_sprint_1;
  1105.     level.scr_anim["zombie"]["crawl_sprint3"]   = %ai_zombie_crawl_sprint_2;
  1106.  
  1107.     if( !isDefined( level._zombie_melee ) )
  1108.     {
  1109.         level._zombie_melee = [];
  1110.     }
  1111.     if( !isDefined( level._zombie_walk_melee ) )
  1112.     {
  1113.         level._zombie_walk_melee = [];
  1114.     }
  1115.     if( !isDefined( level._zombie_run_melee ) )
  1116.     {
  1117.         level._zombie_run_melee = [];
  1118.     }
  1119.  
  1120.     level._zombie_melee["zombie"] = [];
  1121.     level._zombie_walk_melee["zombie"] = [];
  1122.     level._zombie_run_melee["zombie"] = [];
  1123.  
  1124.  
  1125.     level._zombie_melee["zombie"][0]                = %ai_zombie_attack_v2;             // slow swipes
  1126.     level._zombie_melee["zombie"][1]                = %ai_zombie_attack_v4;             // single left swipe
  1127.     level._zombie_melee["zombie"][2]                = %ai_zombie_attack_v6;             // wierd single
  1128. level._zombie_melee["zombie"][3]                = %ai_zombie_attack_v1;             // DOUBLE SWIPE
  1129. level._zombie_melee["zombie"][4]                = %ai_zombie_attack_forward_v1;     // DOUBLE SWIPE
  1130. level._zombie_melee["zombie"][5]                = %ai_zombie_attack_forward_v2;     // slow DOUBLE SWIPE
  1131.    
  1132.     level._zombie_run_melee["zombie"][0]                =   %ai_zombie_run_attack_v1;   // fast single right
  1133.     level._zombie_run_melee["zombie"][1]                =   %ai_zombie_run_attack_v2;   // fast double swipe
  1134.     level._zombie_run_melee["zombie"][2]                =   %ai_zombie_run_attack_v3;   // fast swipe
  1135.  
  1136.     if( isDefined( level.zombie_anim_override ) )
  1137.     {
  1138.         [[ level.zombie_anim_override ]]();
  1139.     }
  1140.  
  1141.     // melee in walk
  1142.     level._zombie_walk_melee["zombie"][0]           = %ai_zombie_walk_attack_v1;    // fast single right swipe
  1143.     level._zombie_walk_melee["zombie"][1]           = %ai_zombie_walk_attack_v2;    // slow right/left single hit
  1144.     level._zombie_walk_melee["zombie"][2]           = %ai_zombie_walk_attack_v3;    // fast single left swipe
  1145.     level._zombie_walk_melee["zombie"][3]           = %ai_zombie_walk_attack_v4;    // slow single right swipe
  1146.  
  1147.     // melee in crawl
  1148.     if( !isDefined( level._zombie_melee_crawl ) )
  1149.     {
  1150.         level._zombie_melee_crawl = [];
  1151.     }
  1152.     level._zombie_melee_crawl["zombie"] = [];
  1153.     level._zombie_melee_crawl["zombie"][0]      = %ai_zombie_attack_crawl;
  1154.     level._zombie_melee_crawl["zombie"][1]      = %ai_zombie_attack_crawl_lunge;
  1155.  
  1156.     if( !isDefined( level._zombie_stumpy_melee ) )
  1157.     {
  1158.         level._zombie_stumpy_melee = [];
  1159.     }
  1160.     level._zombie_stumpy_melee["zombie"] = [];
  1161.     level._zombie_stumpy_melee["zombie"][0] = %ai_zombie_walk_on_hands_shot_a;
  1162.     level._zombie_stumpy_melee["zombie"][1] = %ai_zombie_walk_on_hands_shot_b;
  1163.     //level._zombie_melee_crawl["zombie"][2]        = %ai_zombie_crawl_attack_A;
  1164.  
  1165.     // tesla deaths
  1166.     if( !isDefined( level._zombie_tesla_death ) )
  1167.     {
  1168.         level._zombie_tesla_death = [];
  1169.     }
  1170.     level._zombie_tesla_death["zombie"] = [];
  1171.     level._zombie_tesla_death["zombie"][0] = %ai_zombie_tesla_death_a;
  1172.     level._zombie_tesla_death["zombie"][1] = %ai_zombie_tesla_death_b;
  1173.     level._zombie_tesla_death["zombie"][2] = %ai_zombie_tesla_death_c;
  1174.     level._zombie_tesla_death["zombie"][3] = %ai_zombie_tesla_death_d;
  1175.     level._zombie_tesla_death["zombie"][4] = %ai_zombie_tesla_death_e;
  1176.  
  1177.     if( !isDefined( level._zombie_tesla_crawl_death ) )
  1178.     {
  1179.         level._zombie_tesla_crawl_death = [];
  1180.     }
  1181.     level._zombie_tesla_crawl_death["zombie"] = [];
  1182.     level._zombie_tesla_crawl_death["zombie"][0] = %ai_zombie_tesla_crawl_death_a;
  1183.     level._zombie_tesla_crawl_death["zombie"][1] = %ai_zombie_tesla_crawl_death_b;
  1184.  
  1185.     // thundergun knockdowns and getups
  1186.     if( !isDefined( level._zombie_knockdowns ) )
  1187.     {
  1188.         level._zombie_knockdowns = [];
  1189.     }
  1190.     level._zombie_knockdowns["zombie"] = [];
  1191.     level._zombie_knockdowns["zombie"]["front"] = [];
  1192.  
  1193.     level._zombie_knockdowns["zombie"]["front"]["no_legs"] = [];
  1194.     level._zombie_knockdowns["zombie"]["front"]["no_legs"][0] = %ai_zombie_thundergun_hit_armslegsforward;
  1195.     level._zombie_knockdowns["zombie"]["front"]["no_legs"][1] = %ai_zombie_thundergun_hit_doublebounce;
  1196.     level._zombie_knockdowns["zombie"]["front"]["no_legs"][2] = %ai_zombie_thundergun_hit_forwardtoface;
  1197.  
  1198.     level._zombie_knockdowns["zombie"]["front"]["has_legs"] = [];
  1199.  
  1200.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][0] = %ai_zombie_thundergun_hit_armslegsforward;
  1201.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][1] = %ai_zombie_thundergun_hit_doublebounce;
  1202.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][2] = %ai_zombie_thundergun_hit_upontoback;
  1203.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][3] = %ai_zombie_thundergun_hit_forwardtoface;
  1204.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][4] = %ai_zombie_thundergun_hit_armslegsforward;
  1205.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][5] = %ai_zombie_thundergun_hit_forwardtoface;
  1206.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][6] = %ai_zombie_thundergun_hit_stumblefall;
  1207.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][7] = %ai_zombie_thundergun_hit_armslegsforward;
  1208.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][8] = %ai_zombie_thundergun_hit_doublebounce;
  1209.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][9] = %ai_zombie_thundergun_hit_upontoback;
  1210.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][10] = %ai_zombie_thundergun_hit_forwardtoface;
  1211.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][11] = %ai_zombie_thundergun_hit_armslegsforward;
  1212.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][12] = %ai_zombie_thundergun_hit_forwardtoface;
  1213.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][13] = %ai_zombie_thundergun_hit_deadfallknee;
  1214.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][14] = %ai_zombie_thundergun_hit_armslegsforward;
  1215.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][15] = %ai_zombie_thundergun_hit_doublebounce;
  1216.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][16] = %ai_zombie_thundergun_hit_upontoback;
  1217.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][17] = %ai_zombie_thundergun_hit_forwardtoface;
  1218.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][18] = %ai_zombie_thundergun_hit_armslegsforward;
  1219.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][19] = %ai_zombie_thundergun_hit_forwardtoface;
  1220.     level._zombie_knockdowns["zombie"]["front"]["has_legs"][20] = %ai_zombie_thundergun_hit_flatonback;
  1221.  
  1222.     level._zombie_knockdowns["zombie"]["left"] = [];
  1223.     level._zombie_knockdowns["zombie"]["left"][0] = %ai_zombie_thundergun_hit_legsout_right;
  1224.  
  1225.     level._zombie_knockdowns["zombie"]["right"] = [];
  1226.     level._zombie_knockdowns["zombie"]["right"][0] = %ai_zombie_thundergun_hit_legsout_left;
  1227.  
  1228.     level._zombie_knockdowns["zombie"]["back"] = [];
  1229.     level._zombie_knockdowns["zombie"]["back"][0] = %ai_zombie_thundergun_hit_faceplant;
  1230.  
  1231.     if( !isDefined( level._zombie_getups ) )
  1232.     {
  1233.         level._zombie_getups = [];
  1234.     }
  1235.     level._zombie_getups["zombie"] = [];
  1236.     level._zombie_getups["zombie"]["back"] = [];
  1237.  
  1238.     level._zombie_getups["zombie"]["back"]["early"] = [];
  1239.     level._zombie_getups["zombie"]["back"]["early"][0] = %ai_zombie_thundergun_getup_b;
  1240.     level._zombie_getups["zombie"]["back"]["early"][1] = %ai_zombie_thundergun_getup_c;
  1241.  
  1242.     level._zombie_getups["zombie"]["back"]["late"] = [];
  1243.     level._zombie_getups["zombie"]["back"]["late"][0] = %ai_zombie_thundergun_getup_b;
  1244.     level._zombie_getups["zombie"]["back"]["late"][1] = %ai_zombie_thundergun_getup_c;
  1245.     level._zombie_getups["zombie"]["back"]["late"][2] = %ai_zombie_thundergun_getup_quick_b;
  1246.     level._zombie_getups["zombie"]["back"]["late"][3] = %ai_zombie_thundergun_getup_quick_c;
  1247.  
  1248.     level._zombie_getups["zombie"]["belly"] = [];
  1249.  
  1250.     level._zombie_getups["zombie"]["belly"]["early"] = [];
  1251.     level._zombie_getups["zombie"]["belly"]["early"][0] = %ai_zombie_thundergun_getup_a;
  1252.  
  1253.     level._zombie_getups["zombie"]["belly"]["late"] = [];
  1254.     level._zombie_getups["zombie"]["belly"]["late"][0] = %ai_zombie_thundergun_getup_a;
  1255.     level._zombie_getups["zombie"]["belly"]["late"][1] = %ai_zombie_thundergun_getup_quick_a;
  1256.  
  1257.     // freezegun deaths
  1258.     if( !isDefined( level._zombie_freezegun_death ) )
  1259.     {
  1260.         level._zombie_freezegun_death = [];
  1261.     }
  1262.     level._zombie_freezegun_death["zombie"] = [];
  1263.     level._zombie_freezegun_death["zombie"][0] = %ai_zombie_freeze_death_a;
  1264.     level._zombie_freezegun_death["zombie"][1] = %ai_zombie_freeze_death_b;
  1265.     level._zombie_freezegun_death["zombie"][2] = %ai_zombie_freeze_death_c;
  1266.     level._zombie_freezegun_death["zombie"][3] = %ai_zombie_freeze_death_d;
  1267.     level._zombie_freezegun_death["zombie"][4] = %ai_zombie_freeze_death_e;
  1268.  
  1269.     if( !isDefined( level._zombie_freezegun_death_missing_legs ) )
  1270.     {
  1271.         level._zombie_freezegun_death_missing_legs = [];
  1272.     }
  1273.     level._zombie_freezegun_death_missing_legs["zombie"] = [];
  1274.     level._zombie_freezegun_death_missing_legs["zombie"][0] = %ai_zombie_crawl_freeze_death_01;
  1275.     level._zombie_freezegun_death_missing_legs["zombie"][1] = %ai_zombie_crawl_freeze_death_02;
  1276.  
  1277.     // deaths
  1278.     if( !isDefined( level._zombie_deaths ) )
  1279.     {
  1280.         level._zombie_deaths = [];
  1281.     }
  1282.     level._zombie_deaths["zombie"] = [];
  1283.     level._zombie_deaths["zombie"][0] = %ch_dazed_a_death;
  1284.     level._zombie_deaths["zombie"][1] = %ch_dazed_b_death;
  1285.     level._zombie_deaths["zombie"][2] = %ch_dazed_c_death;
  1286.     level._zombie_deaths["zombie"][3] = %ch_dazed_d_death;
  1287.  
  1288.     /*
  1289.     ground crawl
  1290.     */
  1291.  
  1292.     if( !isDefined( level._zombie_rise_anims ) )
  1293.     {
  1294.         level._zombie_rise_anims = [];
  1295.     }
  1296.  
  1297.     // set up the arrays
  1298.     level._zombie_rise_anims["zombie"] = [];
  1299.  
  1300.     //level._zombie_rise_anims["zombie"][1]["walk"][0]      = %ai_zombie_traverse_ground_v1_crawl;
  1301.     level._zombie_rise_anims["zombie"][1]["walk"][0]        = %ai_zombie_traverse_ground_v1_walk;
  1302.  
  1303.     //level._zombie_rise_anims["zombie"][1]["run"][0]       = %ai_zombie_traverse_ground_v1_crawlfast;
  1304.     level._zombie_rise_anims["zombie"][1]["run"][0]     = %ai_zombie_traverse_ground_v1_run;
  1305.  
  1306.     level._zombie_rise_anims["zombie"][1]["sprint"][0]  = %ai_zombie_traverse_ground_climbout_fast;
  1307.  
  1308.     //level._zombie_rise_anims["zombie"][2]["walk"][0]      = %ai_zombie_traverse_ground_v2_walk;   //!broken
  1309.     level._zombie_rise_anims["zombie"][2]["walk"][0]        = %ai_zombie_traverse_ground_v2_walk_altA;
  1310.     //level._zombie_rise_anims["zombie"][2]["walk"][2]      = %ai_zombie_traverse_ground_v2_walk_altB;//!broken
  1311.  
  1312.     // ground crawl death
  1313.     if( !isDefined( level._zombie_rise_death_anims ) )
  1314.     {
  1315.         level._zombie_rise_death_anims = [];
  1316.     }
  1317.    
  1318.     level._zombie_rise_death_anims["zombie"] = [];
  1319.  
  1320.     level._zombie_rise_death_anims["zombie"][1]["in"][0]        = %ai_zombie_traverse_ground_v1_deathinside;
  1321.     level._zombie_rise_death_anims["zombie"][1]["in"][1]        = %ai_zombie_traverse_ground_v1_deathinside_alt;
  1322.  
  1323.     level._zombie_rise_death_anims["zombie"][1]["out"][0]       = %ai_zombie_traverse_ground_v1_deathoutside;
  1324.     level._zombie_rise_death_anims["zombie"][1]["out"][1]       = %ai_zombie_traverse_ground_v1_deathoutside_alt;
  1325.  
  1326.     level._zombie_rise_death_anims["zombie"][2]["in"][0]        = %ai_zombie_traverse_ground_v2_death_low;
  1327.     level._zombie_rise_death_anims["zombie"][2]["in"][1]        = %ai_zombie_traverse_ground_v2_death_low_alt;
  1328.  
  1329.     level._zombie_rise_death_anims["zombie"][2]["out"][0]       = %ai_zombie_traverse_ground_v2_death_high;
  1330.     level._zombie_rise_death_anims["zombie"][2]["out"][1]       = %ai_zombie_traverse_ground_v2_death_high_alt;
  1331.    
  1332.     //taunts
  1333.     if( !isDefined( level._zombie_run_taunt ) )
  1334.     {
  1335.         level._zombie_run_taunt = [];
  1336.     }
  1337.     if( !isDefined( level._zombie_board_taunt ) )
  1338.     {
  1339.         level._zombie_board_taunt = [];
  1340.     }
  1341.     level._zombie_run_taunt["zombie"] = [];
  1342.     level._zombie_board_taunt["zombie"] = [];
  1343.    
  1344.     //level._zombie_taunt["zombie"][0] = %ai_zombie_taunts_1;
  1345.     //level._zombie_taunt["zombie"][1] = %ai_zombie_taunts_4;
  1346.     //level._zombie_taunt["zombie"][2] = %ai_zombie_taunts_5b;
  1347.     //level._zombie_taunt["zombie"][3] = %ai_zombie_taunts_5c;
  1348.     //level._zombie_taunt["zombie"][4] = %ai_zombie_taunts_5d;
  1349.     //level._zombie_taunt["zombie"][5] = %ai_zombie_taunts_5e;
  1350.     //level._zombie_taunt["zombie"][6] = %ai_zombie_taunts_5f;
  1351.     //level._zombie_taunt["zombie"][7] = %ai_zombie_taunts_7;
  1352.     //level._zombie_taunt["zombie"][8] = %ai_zombie_taunts_9;
  1353.     //level._zombie_taunt["zombie"][8] = %ai_zombie_taunts_11;
  1354.     //level._zombie_taunt["zombie"][8] = %ai_zombie_taunts_12;
  1355.    
  1356.     level._zombie_board_taunt["zombie"][0] = %ai_zombie_taunts_4;
  1357.     level._zombie_board_taunt["zombie"][1] = %ai_zombie_taunts_7;
  1358.     level._zombie_board_taunt["zombie"][2] = %ai_zombie_taunts_9;
  1359.     level._zombie_board_taunt["zombie"][3] = %ai_zombie_taunts_5b;
  1360.     level._zombie_board_taunt["zombie"][4] = %ai_zombie_taunts_5c;
  1361.     level._zombie_board_taunt["zombie"][5] = %ai_zombie_taunts_5d;
  1362.     level._zombie_board_taunt["zombie"][6] = %ai_zombie_taunts_5e;
  1363.     level._zombie_board_taunt["zombie"][7] = %ai_zombie_taunts_5f;
  1364. }
  1365.  
  1366. init_anims()
  1367. {
  1368.     init_standard_zombie_anims();
  1369. }
  1370.  
  1371. // Initialize any animscript related variables
  1372. init_animscripts()
  1373. {
  1374.     // Setup the animscripts, then override them (we call this just incase an AI has not yet spawned)
  1375.     animscripts\zombie_init::firstInit();
  1376.  
  1377.     anim.idleAnimArray      ["stand"] = [];
  1378.     anim.idleAnimWeights    ["stand"] = [];
  1379.     anim.idleAnimArray      ["stand"][0][0]     = %ai_zombie_idle_v1_delta;
  1380.     anim.idleAnimWeights    ["stand"][0][0]     = 10;
  1381.  
  1382.     anim.idleAnimArray      ["crouch"] = [];
  1383.     anim.idleAnimWeights    ["crouch"] = [];   
  1384.     anim.idleAnimArray      ["crouch"][0][0]    = %ai_zombie_idle_crawl_delta;
  1385.     anim.idleAnimWeights    ["crouch"][0][0]    = 10;
  1386. }
  1387.  
  1388. // Handles the intro screen
  1389. zombie_intro_screen( string1, string2, string3, string4, string5 )
  1390. {
  1391.     flag_wait( "all_players_connected" );
  1392. }
  1393.  
  1394. players_playing()
  1395. {
  1396.     // initialize level.players_playing
  1397.     players = get_players();
  1398.     level.players_playing = players.size;
  1399.  
  1400.     wait( 20 );
  1401.  
  1402.     players = get_players();
  1403.     level.players_playing = players.size;
  1404. }
  1405.  
  1406.  
  1407. //  Init some additional settings based on difficulty and number of players
  1408. //
  1409. difficulty_init()
  1410. {
  1411.     flag_wait( "all_players_connected" );
  1412.  
  1413.     difficulty =1;
  1414.     table   = "mp/zombiemode.csv";
  1415.     column  = int(difficulty)+1;
  1416.     players = get_players();
  1417.     points  = 500;
  1418.  
  1419.  
  1420.     // Get individual starting points
  1421.     points = set_zombie_var( ("zombie_score_start_"+players.size+"p"), 3000, false, column );
  1422. /#
  1423.     if( GetDvarInt( #"zombie_cheat" ) >= 1 )
  1424.     {
  1425.         points = 100000;
  1426.     }
  1427. #/
  1428.     for ( p=0; p<players.size; p++ )
  1429.     {
  1430.         players[p].score = points;
  1431.         players[p].score_total = players[p].score;
  1432.         players[p].old_score = players[p].score;
  1433.     }
  1434.  
  1435.     // Get team starting points
  1436.     points = set_zombie_var( ("zombie_team_score_start_"+players.size+"p"), 2000, false, column );
  1437. /#
  1438.     if( GetDvarInt( #"zombie_cheat" ) >= 1 )
  1439.     {
  1440.         points = 100000;
  1441.     }
  1442. #/
  1443.     for ( tp = 0; tp<level.team_pool.size; tp++ )
  1444.     {
  1445.         pool = level.team_pool[ tp ];
  1446.         pool.score          = points;
  1447.         pool.old_score      = pool.score;
  1448.         pool.score_total    = pool.score;
  1449.     }
  1450.  
  1451.     // Other difficulty-specific changes
  1452.     switch ( difficulty )
  1453.     {
  1454.     case "0":
  1455.     case "1":
  1456.         break;
  1457.     case "2":
  1458.         level.first_round   = false;
  1459.         level.round_number  = 8;
  1460.         break;
  1461.     case "3":
  1462.         level.first_round   = false;
  1463.         level.round_number  = 18;
  1464.         break;
  1465.     default:
  1466.         break;
  1467.     }
  1468.  
  1469.     if( level.mutators["mutator_quickStart"] )
  1470.     {
  1471.         level.first_round   = false;
  1472.         level.round_number  = 5;
  1473.     }
  1474. }
  1475.  
  1476.  
  1477. //
  1478. // NETWORK SECTION ====================================================================== //
  1479. //
  1480.  
  1481. watchTakenDamage()
  1482. {
  1483.     self endon( "disconnect" );
  1484.     self endon( "death" );
  1485.  
  1486.     self.has_taken_damage = false;
  1487.     while(1)
  1488.     {
  1489.         self waittill("damage", damage_amount );
  1490.  
  1491.         if ( 0 < damage_amount )
  1492.         {
  1493.             self.has_taken_damage = true;
  1494.             return;
  1495.         }
  1496.     }
  1497. }
  1498.  
  1499. onPlayerConnect()
  1500. {
  1501.     for( ;; )
  1502.     {
  1503.         level waittill( "connecting", player );
  1504.  
  1505.         player.entity_num = player GetEntityNumber();
  1506.         player thread onPlayerSpawned();
  1507.         player thread onPlayerDisconnect();
  1508.         player thread player_revive_monitor();
  1509.  
  1510.         player freezecontrols( true );
  1511.  
  1512.         player thread watchTakenDamage();
  1513.  
  1514.         player.score = 0;
  1515.         player.score_total = player.score;
  1516.         player.old_score = player.score;
  1517.  
  1518.         player.is_zombie = false;
  1519.         player.initialized = false;
  1520.         player.zombification_time = 0;
  1521.         player.enableText = true;
  1522.  
  1523.         player.team_num = 0;
  1524.  
  1525.         player setTeamForEntity( "allies" );
  1526.  
  1527.         //player maps\_zombiemode_protips::player_init();
  1528.        
  1529.         // DCS 090910: now that player can destroy some barricades before set.
  1530.         player thread maps\_zombiemode_blockers::rebuild_barrier_reward_reset();       
  1531.     }
  1532. }
  1533.  
  1534. onPlayerConnect_clientDvars()
  1535. {
  1536.     self SetClientDvars( "cg_deadChatWithDead", "1",
  1537.         "cg_deadChatWithTeam", "1",
  1538.         "cg_deadHearTeamLiving", "1",
  1539.         "cg_deadHearAllLiving", "1",
  1540.         "cg_everyoneHearsEveryone", "1",
  1541.         "compass", "0",
  1542.         "hud_showStance", "0",
  1543.         "cg_thirdPerson", "0",
  1544.         "cg_fov", "65",
  1545.         "cg_thirdPersonAngle", "0",
  1546.         "ammoCounterHide", "1",
  1547.         "miniscoreboardhide", "1",
  1548.         "cg_drawSpectatorMessages", "0",
  1549.         "ui_hud_hardcore", "0",
  1550.         "playerPushAmount", "1" );
  1551.  
  1552.     self SetDepthOfField( 0, 0, 512, 4000, 4, 0 );
  1553.  
  1554.     // Enabling the FPS counter in ship for now
  1555.     //self setclientdvar( "cg_drawfps", "1" );
  1556.    
  1557.     self setClientDvar( "aim_lockon_pitch_strength", 0.0 );
  1558.    
  1559.     if(!level.wii)
  1560.     {
  1561.         //self SetClientDvar("r_enablePlayerShadow", 1);
  1562.     }
  1563. }
  1564.  
  1565.  
  1566.  
  1567. checkForAllDead()
  1568. {
  1569.     players = get_players();
  1570.     count = 0;
  1571.     for( i = 0; i < players.size; i++ )
  1572.     {
  1573.         if( !(players[i] maps\_laststand::player_is_in_laststand()) && !(players[i].sessionstate == "spectator") )
  1574.         {
  1575.             count++;
  1576.         }
  1577.     }
  1578.    
  1579.     if( count==0 )
  1580.     {
  1581.         level notify( "end_game" );
  1582.     }
  1583. }
  1584.    
  1585.  
  1586. onPlayerDisconnect()
  1587. {
  1588.     self waittill( "disconnect" );
  1589.     self remove_from_spectate_list();
  1590.     self checkForAllDead();
  1591. }
  1592.  
  1593.  
  1594. //
  1595. //  Runs when the player spawns into the map
  1596. //  self is the player.surprise!
  1597. //
  1598. onPlayerSpawned()
  1599. {
  1600.     self endon( "disconnect" );
  1601.  
  1602.     for( ;; )
  1603.     {
  1604.         self waittill( "spawned_player" );
  1605.        
  1606.         self freezecontrols( false );
  1607.  
  1608.         self init_player_offhand_weapons();
  1609.  
  1610.         self enablehealthshield( false );
  1611. /#
  1612.         if ( GetDvarInt( #"zombie_cheat" ) >= 1 && GetDvarInt( #"zombie_cheat" ) <= 3 )
  1613.         {
  1614.             self EnableInvulnerability();
  1615.         }
  1616. #/
  1617.  
  1618.         self PlayerKnockback( false );
  1619.  
  1620.         self SetClientDvars( "cg_thirdPerson", "0",
  1621.             "cg_fov", "65",
  1622.             "cg_thirdPersonAngle", "0" );
  1623.  
  1624.         self SetDepthOfField( 0, 0, 512, 4000, 4, 0 );
  1625.  
  1626.         self cameraactivate(false);
  1627.  
  1628.         self add_to_spectate_list();
  1629.        
  1630.         self.num_perks = 0;
  1631.         self.on_lander_last_stand = undefined;
  1632.        
  1633.         if ( is_true( level.player_out_of_playable_area_monitor ) )
  1634.         {
  1635.             self thread player_out_of_playable_area_monitor();
  1636.         }
  1637.  
  1638.         if ( is_true( level.player_too_many_weapons_monitor ) )
  1639.         {
  1640.             self thread [[level.player_too_many_weapons_monitor_func]]();
  1641.         }
  1642.  
  1643.         if( isdefined( self.initialized ) )
  1644.         {
  1645.             if( self.initialized == false )
  1646.             {
  1647.                 self.initialized = true;
  1648.                
  1649.                 self freezecontrols( true ); // first spawn only, intro_black_screen will pull them out of it
  1650.  
  1651.                 // ww: set the is_drinking variable
  1652.                 self.is_drinking = 0;
  1653.  
  1654.                 // set the initial score on the hud    
  1655.                 self maps\_zombiemode_score::set_player_score_hud( true );
  1656.                 self thread player_zombie_breadcrumb();            
  1657.            
  1658.                 // This will keep checking to see if you're trying to use an ability.
  1659.                 //self thread maps\_zombiemode_ability::hardpointItemWaiter();
  1660.  
  1661.                 //self thread maps\_zombiemode_ability::hardPointItemSelector();
  1662.  
  1663.                 //Init stat tracking variables
  1664.                 self.stats["kills"] = 0;
  1665.                 self.stats["score"] = 0;
  1666.                 self.stats["downs"] = 0;
  1667.                 self.stats["revives"] = 0;
  1668.                 self.stats["perks"] = 0;
  1669.                 self.stats["headshots"] = 0;
  1670.                 self.stats["zombie_gibs"] = 0;
  1671.                
  1672.                 //track damage taken by this player
  1673.                 self.stats["damage_taken"] = 0;
  1674.                
  1675.                 //track player distance traveled
  1676.                 self.stats["distance_traveled"] = 0;
  1677.                 self thread player_monitor_travel_dist();  
  1678.  
  1679.                 self thread player_grenade_watcher();
  1680.                
  1681.             }
  1682.         }
  1683.     }
  1684. }
  1685.  
  1686.  
  1687. spawn_life_brush( origin, radius, height )
  1688. {
  1689.     life_brush = spawn( "trigger_radius", origin, 0, radius, height );
  1690.     life_brush.script_noteworthy = "life_brush";
  1691.    
  1692.     return life_brush;
  1693. }
  1694.  
  1695.  
  1696. in_life_brush()
  1697. {
  1698.     life_brushes = getentarray( "life_brush", "script_noteworthy" );
  1699.  
  1700.     if ( !IsDefined( life_brushes ) )
  1701.     {
  1702.         return false;
  1703.     }
  1704.    
  1705.     for ( i = 0; i < life_brushes.size; i++ )
  1706.     {
  1707.  
  1708.         if ( self IsTouching( life_brushes[i] ) )
  1709.         {
  1710.             return true;
  1711.         }
  1712.     }
  1713.  
  1714.     return false;
  1715. }
  1716.  
  1717.  
  1718. spawn_kill_brush( origin, radius, height )
  1719. {
  1720.     kill_brush = spawn( "trigger_radius", origin, 0, radius, height );
  1721.     kill_brush.script_noteworthy = "kill_brush";
  1722.    
  1723.     return kill_brush;
  1724. }
  1725.  
  1726.  
  1727. in_kill_brush()
  1728. {
  1729.     kill_brushes = getentarray( "kill_brush", "script_noteworthy" );
  1730.  
  1731.     if ( !IsDefined( kill_brushes ) )
  1732.     {
  1733.         return false;
  1734.     }
  1735.    
  1736.     for ( i = 0; i < kill_brushes.size; i++ )
  1737.     {
  1738.  
  1739.         if ( self IsTouching( kill_brushes[i] ) )
  1740.         {
  1741.             return true;
  1742.         }
  1743.     }
  1744.  
  1745.     return false;
  1746. }
  1747.  
  1748.  
  1749. in_enabled_playable_area()
  1750. {
  1751.     playable_area = getentarray( "player_volume", "script_noteworthy" );
  1752.  
  1753.     if( !IsDefined( playable_area ) )
  1754.     {
  1755.         return false;
  1756.     }
  1757.    
  1758.     for ( i = 0; i < playable_area.size; i++ )
  1759.     {
  1760.         if ( maps\_zombiemode_zone_manager::zone_is_enabled( playable_area[i].targetname ) && self IsTouching( playable_area[i] ) )
  1761.         {
  1762.             return true;
  1763.         }
  1764.     }
  1765.  
  1766.     return false;
  1767. }
  1768.  
  1769.  
  1770. get_player_out_of_playable_area_monitor_wait_time()
  1771. {
  1772. /#
  1773.     if ( is_true( level.check_kill_thread_every_frame ) )
  1774.     {
  1775.         return 0.05;
  1776.     }
  1777. #/
  1778.  
  1779.     return 3;
  1780. }
  1781.  
  1782.  
  1783. player_out_of_playable_area_monitor()
  1784. {
  1785.     self notify( "stop_player_out_of_playable_area_monitor" );
  1786.     self endon( "stop_player_out_of_playable_area_monitor" );
  1787.     self endon( "disconnect" );
  1788.     level endon( "end_game" );
  1789.  
  1790.     // load balancing
  1791.     wait( (0.15 * self GetEntityNumber()) );
  1792.  
  1793.     while ( true )
  1794.     {
  1795.         // skip over players in spectate, otherwise Sam keeps laughing every 3 seconds since their corpse is still invisibly in a kill area
  1796.         if ( self.sessionstate == "spectator" )
  1797.         {
  1798.             wait( get_player_out_of_playable_area_monitor_wait_time() );
  1799.             continue;
  1800.         }
  1801.  
  1802.         if ( !self in_life_brush() && (self in_kill_brush() || !self in_enabled_playable_area()) )
  1803.         {
  1804.             if ( !isdefined( level.player_out_of_playable_area_monitor_callback ) || self [[level.player_out_of_playable_area_monitor_callback]]() )
  1805.             {
  1806. /#
  1807.                 //iprintlnbold( "out of playable" );
  1808.                 if ( isdefined( self isinmovemode( "ufo", "noclip" ) ) || is_true( level.disable_kill_thread ) || GetDvarInt( "zombie_cheat" ) > 0 )
  1809.                 {
  1810.                     wait( get_player_out_of_playable_area_monitor_wait_time() );
  1811.                     continue;
  1812.                 }
  1813. #/
  1814.                 if( is_true( level.player_4_vox_override ) )
  1815.                 {
  1816.                     self playlocalsound( "zmb_laugh_rich" );
  1817.                 }
  1818.                 else
  1819.                 {
  1820.                     self playlocalsound( "zmb_laugh_child" );  
  1821.                 }
  1822.                
  1823.                 wait( 0.5 );
  1824.  
  1825.                 if ( getplayers().size == 1 && flag( "solo_game" ) && is_true( self.waiting_to_revive ) )
  1826.                 {
  1827.                     level notify( "end_game" );
  1828.                 }
  1829.                 else
  1830.                 {
  1831.                     self.lives = 0;
  1832.                     self dodamage( self.health + 1000, self.origin );
  1833.                     self.bleedout_time = 0;
  1834.                 }
  1835.             }
  1836.         }
  1837.  
  1838.         wait( get_player_out_of_playable_area_monitor_wait_time() );
  1839.     }
  1840. }
  1841.  
  1842.  
  1843. get_player_too_many_weapons_monitor_wait_time()
  1844. {
  1845.     return 3;
  1846. }
  1847.  
  1848.  
  1849. player_too_many_weapons_monitor_takeaway_simultaneous( primary_weapons_to_take )
  1850. {
  1851.     self endon( "player_too_many_weapons_monitor_takeaway_sequence_done" );
  1852.  
  1853.     self waittill_any( "player_downed", "replace_weapon_powerup" );
  1854.  
  1855.     for ( i = 0; i < primary_weapons_to_take.size; i++ )
  1856.     {
  1857.         self TakeWeapon( primary_weapons_to_take[i] );
  1858.     }
  1859.  
  1860.     self maps\_zombiemode_score::minus_to_player_score( self.score );
  1861.     self GiveWeapon( "m1911_zm" );
  1862.     if ( !self maps\_laststand::player_is_in_laststand() )
  1863.     {
  1864.         self decrement_is_drinking();
  1865.     }
  1866.     else if ( flag( "solo_game" ) )
  1867.     {
  1868.         self.score_lost_when_downed = 0;
  1869.     }
  1870.  
  1871.     self notify( "player_too_many_weapons_monitor_takeaway_sequence_done" );
  1872. }
  1873.  
  1874.  
  1875. player_too_many_weapons_monitor_takeaway_sequence( primary_weapons_to_take )
  1876. {
  1877.     self thread player_too_many_weapons_monitor_takeaway_simultaneous( primary_weapons_to_take );
  1878.  
  1879.     self endon( "player_downed" );
  1880.     self endon( "replace_weapon_powerup" );
  1881.  
  1882.     self increment_is_drinking();
  1883.     score_decrement = round_up_to_ten( int( self.score / (primary_weapons_to_take.size + 1) ) );
  1884.  
  1885.     for ( i = 0; i < primary_weapons_to_take.size; i++ )
  1886.     {
  1887.         if( is_true( level.player_4_vox_override ) )
  1888.         {
  1889.             self playlocalsound( "zmb_laugh_rich" );
  1890.         }
  1891.         else
  1892.         {
  1893.             self playlocalsound( "zmb_laugh_child" );  
  1894.         }
  1895.         self SwitchToWeapon( primary_weapons_to_take[i] );
  1896.         self maps\_zombiemode_score::minus_to_player_score( score_decrement );
  1897.         wait( 3 );
  1898.  
  1899.         self TakeWeapon( primary_weapons_to_take[i] );
  1900.     }
  1901.  
  1902.     if( is_true( level.player_4_vox_override ) )
  1903.     {
  1904.         self playlocalsound( "zmb_laugh_rich" );
  1905.     }
  1906.     else
  1907.     {
  1908.         self playlocalsound( "zmb_laugh_child" );  
  1909.     }
  1910.     self maps\_zombiemode_score::minus_to_player_score( self.score );
  1911.     wait( 1 );
  1912.     self GiveWeapon( "m1911_zm" );
  1913.     self SwitchToWeapon( "m1911_zm" );
  1914.     self decrement_is_drinking();
  1915.  
  1916.     self notify( "player_too_many_weapons_monitor_takeaway_sequence_done" );
  1917. }
  1918.  
  1919.  
  1920. player_too_many_weapons_monitor()
  1921. {
  1922.     self notify( "stop_player_too_many_weapons_monitor" );
  1923.     self endon( "stop_player_too_many_weapons_monitor" );
  1924.     self endon( "disconnect" );
  1925.     level endon( "end_game" );
  1926.  
  1927.     // load balancing
  1928.     wait( (0.15 * self GetEntityNumber()) );
  1929.  
  1930.     while ( true )
  1931.     {
  1932.         if ( self has_powerup_weapon() || self maps\_laststand::player_is_in_laststand() || self.sessionstate == "spectator" )
  1933.         {
  1934.             wait( get_player_too_many_weapons_monitor_wait_time() );
  1935.             continue;
  1936.         }
  1937.  
  1938. /#
  1939.         if ( GetDvarInt( "zombie_cheat" ) > 0 )
  1940.         {
  1941.             wait( get_player_too_many_weapons_monitor_wait_time() );
  1942.             continue;
  1943.         }
  1944. #/
  1945.  
  1946.         primary_weapons_to_take = [];
  1947.         weapon_limit = 2;
  1948.         if ( self HasPerk( "specialty_additionalprimaryweapon" ) )
  1949.         {
  1950.             weapon_limit = 3;
  1951.         }
  1952.  
  1953.         primaryWeapons = self GetWeaponsListPrimaries();
  1954.         for ( i = 0; i < primaryWeapons.size; i++ )
  1955.         {
  1956.             if ( maps\_zombiemode_weapons::is_weapon_included( primaryWeapons[i] ) || maps\_zombiemode_weapons::is_weapon_upgraded( primaryWeapons[i] ) )
  1957.             {
  1958.                 primary_weapons_to_take[primary_weapons_to_take.size] = primaryWeapons[i];
  1959.             }
  1960.         }
  1961.  
  1962.         if ( primary_weapons_to_take.size > weapon_limit )
  1963.         {
  1964.             if ( !isdefined( level.player_too_many_weapons_monitor_callback ) || self [[level.player_too_many_weapons_monitor_callback]]( primary_weapons_to_take ) )
  1965.             {
  1966.                 self thread player_too_many_weapons_monitor_takeaway_sequence( primary_weapons_to_take );
  1967.                 self waittill( "player_too_many_weapons_monitor_takeaway_sequence_done" );
  1968.             }
  1969.         }
  1970.  
  1971.         wait( get_player_too_many_weapons_monitor_wait_time() );
  1972.     }
  1973. }
  1974.  
  1975.  
  1976. player_monitor_travel_dist()
  1977. {
  1978.     self endon("disconnect");
  1979.    
  1980.     prevpos = self.origin;
  1981.     while(1)
  1982.     {
  1983.         wait .1;
  1984.  
  1985.         self.stats["distance_traveled"] += distance( self.origin, prevpos );
  1986.         prevpos = self.origin;
  1987.     }
  1988. }
  1989.  
  1990. player_grenade_watcher()
  1991. {
  1992.     self endon( "disconnect" );
  1993.  
  1994.     while ( 1 )
  1995.     {
  1996.         self waittill( "grenade_fire", grenade, weapName );
  1997.  
  1998.         if( isdefined( grenade ) && isalive( grenade ) )
  1999.         {
  2000.             grenade.team = self.team;
  2001.         }
  2002.     }
  2003. }
  2004.  
  2005. player_prevent_damage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
  2006. {
  2007.     if ( eInflictor == self || eAttacker == self )
  2008.     {
  2009.         return false;
  2010.     }
  2011.  
  2012.     if ( isdefined( eInflictor ) && isdefined( eInflictor.team ) )
  2013.     {
  2014.         if ( eInflictor.team == self.team )
  2015.         {
  2016.             return true;
  2017.         }
  2018.     }
  2019.  
  2020.     return false;
  2021. }
  2022.  
  2023. //
  2024. //  Keep track of players going down and getting revived
  2025. player_revive_monitor()
  2026. {
  2027.     self endon( "disconnect" );
  2028.  
  2029.     while (1)
  2030.     {
  2031.         self waittill( "player_revived", reviver );
  2032.        
  2033.         //AYERS: Working on Laststand Audio
  2034.         //self clientnotify( "revived" );
  2035.        
  2036.         bbPrint( "zombie_playerdeaths: round %d playername %s deathtype revived x %f y %f z %f", level.round_number, self.playername, self.origin );
  2037.  
  2038.         //self laststand_giveback_player_perks();
  2039.  
  2040.         if ( IsDefined(reviver) )
  2041.         {
  2042.             self maps\_zombiemode_audio::create_and_play_dialog( "general", "revive_up" );
  2043.            
  2044.             //reviver maps\_zombiemode_rank::giveRankXp( "revive" );
  2045.             //maps\_zombiemode_challenges::doMissionCallback( "zm_revive", reviver );
  2046.  
  2047.             // Check to see how much money you lost from being down.
  2048.             points = self.score_lost_when_downed;
  2049.             reviver maps\_zombiemode_score::player_add_points( "reviver", points );
  2050.             self.score_lost_when_downed = 0;
  2051.         }
  2052.     }
  2053. }
  2054.  
  2055.  
  2056. // self = a player
  2057. // If the player has just 1 perk, they wil always get it back
  2058. // If the player has more than 1 perk, they will lose a single perk
  2059. laststand_giveback_player_perks()
  2060. {
  2061.     if ( IsDefined( self.laststand_perks ) )
  2062.     {
  2063.         // Calculate a lost perk index
  2064.         lost_perk_index = int( -1 );
  2065.         if( self.laststand_perks.size > 1 )
  2066.         {
  2067.             lost_perk_index = RandomInt( self.laststand_perks.size-1 );
  2068.         }
  2069.        
  2070.         // Give the player back their perks
  2071.         for ( i=0; i<self.laststand_perks.size; i++ )
  2072.         {
  2073.             if ( self HasPerk( self.laststand_perks[i] ) )
  2074.             {
  2075.                 continue;
  2076.             }
  2077.             if( i == lost_perk_index )
  2078.             {
  2079.                 continue;
  2080.             }
  2081.            
  2082.             maps\_zombiemode_perks::give_perk( self.laststand_perks[i] );
  2083.         }
  2084.     }
  2085. }
  2086.  
  2087. remote_revive_watch()
  2088. {
  2089.     self endon( "death" );
  2090.     self endon( "player_revived" );
  2091.  
  2092.     self waittill( "remote_revive", reviver );
  2093.  
  2094.     self maps\_laststand::remote_revive( reviver );
  2095. }
  2096.  
  2097. remove_deadshot_bottle()
  2098. {
  2099.     wait( 0.05 );
  2100.  
  2101.     if ( isdefined( self.lastActiveWeapon ) && self.lastActiveWeapon == "zombie_perk_bottle_deadshot" )
  2102.     {
  2103.         self.lastActiveWeapon = "none";
  2104.     }
  2105. }
  2106.  
  2107. take_additionalprimaryweapon()
  2108. {
  2109.     weapon_to_take = undefined;
  2110.  
  2111.     if ( is_true( self._retain_perks ) )
  2112.     {
  2113.         return weapon_to_take;
  2114.     }
  2115.  
  2116.     primary_weapons_that_can_be_taken = [];
  2117.  
  2118.     primaryWeapons = self GetWeaponsListPrimaries();
  2119.     for ( i = 0; i < primaryWeapons.size; i++ )
  2120.     {
  2121.         if ( maps\_zombiemode_weapons::is_weapon_included( primaryWeapons[i] ) || maps\_zombiemode_weapons::is_weapon_upgraded( primaryWeapons[i] ) )
  2122.         {
  2123.             primary_weapons_that_can_be_taken[primary_weapons_that_can_be_taken.size] = primaryWeapons[i];
  2124.         }
  2125.     }
  2126.  
  2127.     if ( primary_weapons_that_can_be_taken.size >= 3 )
  2128.     {
  2129.         weapon_to_take = primary_weapons_that_can_be_taken[primary_weapons_that_can_be_taken.size - 1];
  2130.         if ( weapon_to_take == self GetCurrentWeapon() )
  2131.         {
  2132.             self SwitchToWeapon( primary_weapons_that_can_be_taken[0] );
  2133.         }
  2134.         self TakeWeapon( weapon_to_take );
  2135.     }
  2136.  
  2137.     return weapon_to_take;
  2138. }
  2139.  
  2140. player_laststand( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
  2141. {
  2142.     // Grab the perks, we'll give them back to the player if he's revived
  2143.     //self.laststand_perks = maps\_zombiekmode_deathcard::deathcard_save_perks( self );
  2144.  
  2145.     if ( self HasPerk( "specialty_additionalprimaryweapon" ) )
  2146.     {
  2147.         self.weapon_taken_by_losing_specialty_additionalprimaryweapon = self take_additionalprimaryweapon();
  2148.     }
  2149.  
  2150.     //AYERS: Working on Laststand Audio
  2151.     /*
  2152.     players = get_players();
  2153.     if( players.size >= 2 )
  2154.     {
  2155.         self clientnotify( "lststnd" );
  2156.     }
  2157.     */
  2158.    
  2159.         //if ( IsDefined( level.deathcard_laststand_func ) )
  2160.     //{
  2161.     //  self [[ level.deathcard_laststand_func ]]();
  2162.     //}
  2163.     self clear_is_drinking();
  2164.  
  2165.     self thread remove_deadshot_bottle();
  2166.    
  2167.     self thread remote_revive_watch();
  2168.    
  2169.     self maps\_zombiemode_score::player_downed_penalty();
  2170.    
  2171.     // Turns out we need to do this after all, but we don't want to change _laststand.gsc postship, so I'm doing it here manually instead
  2172.     self DisableOffhandWeapons();
  2173.  
  2174.     self thread last_stand_grenade_save_and_return();
  2175.    
  2176.     if( sMeansOfDeath != "MOD_SUICIDE" && sMeansOfDeath != "MOD_FALLING" )
  2177.     {
  2178.         self maps\_zombiemode_audio::create_and_play_dialog( "general", "revive_down" );
  2179.     }
  2180.    
  2181.     bbPrint( "zombie_playerdeaths: round %d playername %s deathtype downed x %f y %f z %f", level.round_number, self.playername, self.origin );
  2182.    
  2183.     if( IsDefined( level._zombie_minigun_powerup_last_stand_func ) )
  2184.     {
  2185.         self thread [[level._zombie_minigun_powerup_last_stand_func]]();
  2186.     }
  2187.    
  2188.     if( IsDefined( level._zombie_tesla_powerup_last_stand_func ) )
  2189.     {
  2190.         self thread [[level._zombie_tesla_powerup_last_stand_func]]();
  2191.     }
  2192.  
  2193.     if( IsDefined( self.intermission ) && self.intermission )
  2194.     {
  2195.         //maps\_zombiemode_challenges::doMissionCallback( "playerDied", self );
  2196.  
  2197.         bbPrint( "zombie_playerdeaths: round %d playername %s deathtype died x %f y %f z %f", level.round_number, self.playername, self.origin );
  2198.  
  2199.         level waittill( "forever" );
  2200.     }
  2201. }
  2202.  
  2203.  
  2204. failsafe_revive_give_back_weapons()
  2205. {
  2206.     for ( i = 0; i < 10; i++ )
  2207.     {
  2208.         wait( 0.05 );
  2209.        
  2210.         if ( !isdefined( self.reviveProgressBar ) )
  2211.         {
  2212.             continue;
  2213.         }
  2214.  
  2215.         players = get_players();
  2216.         for ( playerIndex = 0; playerIndex < players.size; playerIndex++ )
  2217.         {
  2218.             revivee = players[playerIndex];
  2219.  
  2220.             if ( self maps\_laststand::is_reviving( revivee ) )
  2221.             {
  2222.                 // don't clean up revive stuff if he is reviving someone else
  2223.                 continue;
  2224.             }
  2225.         }
  2226.  
  2227.         // he's not reviving anyone but he still has revive stuff up, clean it all up
  2228. /#
  2229. iprintlnbold( "FAILSAFE CLEANING UP REVIVE HUD AND GUN" );
  2230. #/
  2231.         // pass in "none" since we have no idea what the weapon they should be showing is
  2232.         self maps\_laststand::revive_give_back_weapons( "none" );
  2233.  
  2234.         if ( isdefined( self.reviveProgressBar ) )
  2235.         {
  2236.             self.reviveProgressBar maps\_hud_util::destroyElem();
  2237.         }
  2238.  
  2239.         if ( isdefined( self.reviveTextHud ) )
  2240.         {
  2241.             self.reviveTextHud destroy();
  2242.         }
  2243.  
  2244.         return;
  2245.     }
  2246. }
  2247.  
  2248.  
  2249. spawnSpectator()
  2250. {
  2251.     self endon( "disconnect" );
  2252.     self endon( "spawned_spectator" );
  2253.     self notify( "spawned" );
  2254.     self notify( "end_respawn" );
  2255.  
  2256.     if( level.intermission )
  2257.     {
  2258.         return;
  2259.     }
  2260.  
  2261.     if( IsDefined( level.no_spectator ) && level.no_spectator )
  2262.     {
  2263.         wait( 3 );
  2264.         ExitLevel();
  2265.     }
  2266.  
  2267.     // The check_for_level_end looks for this
  2268.     self.is_zombie = true;
  2269.  
  2270.     //failsafe against losing viewarms due to the thread returning them getting an endon from "zombified"
  2271.     players = get_players();
  2272.     for ( i = 0; i < players.size; i++ )
  2273.     {
  2274.         if ( self != players[i] )
  2275.         {
  2276.             players[i] thread failsafe_revive_give_back_weapons();
  2277.         }
  2278.     }
  2279.  
  2280.     // Remove all reviving abilities
  2281.     self notify ( "zombified" );
  2282.  
  2283.     if( IsDefined( self.revivetrigger ) )
  2284.     {
  2285.         self.revivetrigger delete();
  2286.         self.revivetrigger = undefined;
  2287.     }
  2288.  
  2289.     self.zombification_time = GetTime(); //set time when player died
  2290.  
  2291.     resetTimeout();
  2292.  
  2293.     // Stop shellshock and rumble
  2294.     self StopShellshock();
  2295.     self StopRumble( "damage_heavy" );
  2296.  
  2297.     self.sessionstate = "spectator";
  2298.     self.spectatorclient = -1;
  2299.  
  2300.     self remove_from_spectate_list();
  2301.  
  2302.     self.maxhealth = self.health;
  2303.     self.shellshocked = false;
  2304.     self.inWater = false;
  2305.     self.friendlydamage = undefined;
  2306.     self.hasSpawned = true;
  2307.     self.spawnTime = GetTime();
  2308.     self.afk = false;
  2309.  
  2310.     println( "*************************Zombie Spectator***" );
  2311.     self detachAll();
  2312.  
  2313.     self setSpectatePermissions( true );
  2314.     self thread spectator_thread();
  2315.  
  2316.     self Spawn( self.origin, self.angles );
  2317.     self notify( "spawned_spectator" );
  2318. }
  2319.  
  2320. setSpectatePermissions( isOn )
  2321. {
  2322.     self AllowSpectateTeam( "allies", isOn );
  2323.     self AllowSpectateTeam( "axis", false );
  2324.     self AllowSpectateTeam( "freelook", false );
  2325.     self AllowSpectateTeam( "none", false );   
  2326. }
  2327.  
  2328. spectator_thread()
  2329. {
  2330.     self endon( "disconnect" );
  2331.     self endon( "spawned_player" );
  2332.  
  2333. /*  we are not currently supporting the shared screen tech
  2334.     if( IsSplitScreen() )
  2335.     {
  2336.         last_alive = undefined;
  2337.         players = get_players();
  2338.  
  2339.         for( i = 0; i < players.size; i++ )
  2340.         {
  2341.             if( !players[i].is_zombie )
  2342.             {
  2343.                 last_alive = players[i];
  2344.             }
  2345.         }
  2346.  
  2347.         share_screen( last_alive, true );
  2348.  
  2349.         return;
  2350.     }
  2351. */
  2352.  
  2353. //  self thread spectator_toggle_3rd_person();
  2354. }
  2355.  
  2356. spectator_toggle_3rd_person()
  2357. {
  2358.     self endon( "disconnect" );
  2359.     self endon( "spawned_player" );
  2360.  
  2361.     third_person = true;
  2362.     self set_third_person( true );
  2363.     //  self NotifyOnCommand( "toggle_3rd_person", "weapnext" );
  2364.  
  2365.     //  while( 1 )
  2366.     //  {
  2367.     //      self waittill( "toggle_3rd_person" );
  2368.     //
  2369.     //      if( third_person )
  2370.     //      {
  2371.     //          third_person = false;
  2372.     //          self set_third_person( false );
  2373.     //          wait( 0.5 );
  2374.     //      }
  2375.     //      else
  2376.     //      {
  2377.     //          third_person = true;
  2378.     //          self set_third_person( true );
  2379.     //          wait( 0.5 );
  2380.     //      }
  2381.     //  }
  2382. }
  2383.  
  2384.  
  2385. set_third_person( value )
  2386. {
  2387.     if( value )
  2388.     {
  2389.         self SetClientDvars( "cg_thirdPerson", "1",
  2390.             "cg_fov", "40",
  2391.             "cg_thirdPersonAngle", "354" );
  2392.  
  2393.         self setDepthOfField( 0, 128, 512, 4000, 6, 1.8 );
  2394.     }
  2395.     else
  2396.     {
  2397.         self SetClientDvars( "cg_thirdPerson", "0",
  2398.             "cg_fov", "65",
  2399.             "cg_thirdPersonAngle", "0" );
  2400.  
  2401.         self setDepthOfField( 0, 0, 512, 4000, 4, 0 );
  2402.     }
  2403. }
  2404.  
  2405. last_stand_revive()
  2406. {
  2407.     level endon( "between_round_over" );
  2408.  
  2409.     players = getplayers();
  2410.  
  2411.     for ( i = 0; i < players.size; i++ )
  2412.     {
  2413.         if ( players[i] maps\_laststand::player_is_in_laststand() && players[i].revivetrigger.beingRevived == 0 )
  2414.         {
  2415.             players[i] maps\_laststand::auto_revive();
  2416.         }
  2417.     }
  2418. }
  2419.  
  2420. // ww: arrange the last stand pistols so when it come time to choose which one they are inited
  2421. last_stand_pistol_rank_init()
  2422. {
  2423.     level.pistol_values = [];
  2424.    
  2425.     flag_wait( "_start_zm_pistol_rank" );
  2426.    
  2427.     if( flag( "solo_game" ) )
  2428.     {
  2429.         // ww: in a solo game the ranking of the pistols is a bit different based on the upgraded 1911 swap
  2430.         // any pistol ranked 4 or lower will be ignored and the player will be given the upgraded 1911
  2431.         level.pistol_values[ level.pistol_values.size ] = "m1911_zm";
  2432.         level.pistol_values[ level.pistol_values.size ] = "cz75_zm";
  2433.         level.pistol_values[ level.pistol_values.size ] = "cz75dw_zm";
  2434.         level.pistol_values[ level.pistol_values.size ] = "python_zm";
  2435.         level.pistol_values[ level.pistol_values.size ] = "python_upgraded_zm"; // ww: this is spot 4, anything scoring lower than this should be replaced
  2436.         level.pistol_values[ level.pistol_values.size ] = "cz75_upgraded_zm";
  2437.         level.pistol_values[ level.pistol_values.size ] = "cz75dw_upgraded_zm";
  2438.         level.pistol_values[ level.pistol_values.size ] = "m1911_upgraded_zm";
  2439.         level.pistol_values[ level.pistol_values.size ] = "ray_gun_zm";
  2440.         level.pistol_values[ level.pistol_values.size ] = "freezegun_zm";
  2441.         level.pistol_values[ level.pistol_values.size ] = "ray_gun_upgraded_zm";
  2442.         level.pistol_values[ level.pistol_values.size ] = "freezegun_upgraded_zm";
  2443.         level.pistol_values[ level.pistol_values.size ] = "microwavegundw_zm";
  2444.         level.pistol_values[ level.pistol_values.size ] = "microwavegundw_upgraded_zm";
  2445.     }
  2446.     else
  2447.     {
  2448.         level.pistol_values[ level.pistol_values.size ] = "m1911_zm";
  2449.         level.pistol_values[ level.pistol_values.size ] = "cz75_zm";
  2450.         level.pistol_values[ level.pistol_values.size ] = "cz75dw_zm";
  2451.         level.pistol_values[ level.pistol_values.size ] = "python_zm";
  2452.         level.pistol_values[ level.pistol_values.size ] = "python_upgraded_zm";
  2453.         level.pistol_values[ level.pistol_values.size ] = "cz75_upgraded_zm";
  2454.         level.pistol_values[ level.pistol_values.size ] = "cz75dw_upgraded_zm";
  2455.         level.pistol_values[ level.pistol_values.size ] = "m1911_upgraded_zm";
  2456.         level.pistol_values[ level.pistol_values.size ] = "ray_gun_zm";
  2457.         level.pistol_values[ level.pistol_values.size ] = "freezegun_zm";
  2458.         level.pistol_values[ level.pistol_values.size ] = "ray_gun_upgraded_zm";
  2459.         level.pistol_values[ level.pistol_values.size ] = "freezegun_upgraded_zm";
  2460.         level.pistol_values[ level.pistol_values.size ] = "microwavegundw_zm";
  2461.         level.pistol_values[ level.pistol_values.size ] = "microwavegundw_upgraded_zm";
  2462.     }
  2463.  
  2464. }
  2465.  
  2466. // ww: changing the _laststand scripts to this one so we interfere with SP less
  2467. last_stand_pistol_swap()
  2468. {
  2469.     if ( self has_powerup_weapon() )
  2470.     {
  2471.         // this will force the laststand module to switch us to any primary weapon, since we will no longer have this after revive
  2472.         self.lastActiveWeapon = "none";
  2473.     }
  2474.  
  2475.     if ( !self HasWeapon( self.laststandpistol ) )
  2476.     {
  2477.         self GiveWeapon( self.laststandpistol );
  2478.     }
  2479.     ammoclip = WeaponClipSize( self.laststandpistol );
  2480.     doubleclip = ammoclip * 2;
  2481.    
  2482.     if( is_true( self._special_solo_pistol_swap ) || (self.laststandpistol == "m1911_upgraded_zm" && !self.hadpistol) )
  2483.     {
  2484.         self._special_solo_pistol_swap = 0;
  2485.         self.hadpistol = false;
  2486.         self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
  2487.     }
  2488.     else if( flag("solo_game") && self.laststandpistol == "m1911_upgraded_zm")
  2489.     {
  2490.         self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
  2491.     }
  2492.     else if ( self.laststandpistol == "m1911_zm" )
  2493.     {
  2494.         self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
  2495.     }
  2496.     else if ( self.laststandpistol == "ray_gun_zm" || self.laststandpistol == "ray_gun_upgraded_zm" )
  2497.     {
  2498.         if ( self.stored_weapon_info[ self.laststandpistol ].total_amt >= ammoclip )
  2499.         {
  2500.             self SetWeaponAmmoClip( self.laststandpistol, ammoclip );
  2501.             self.stored_weapon_info[ self.laststandpistol ].given_amt = ammoclip;
  2502.         }
  2503.         else
  2504.         {
  2505.             self SetWeaponAmmoClip( self.laststandpistol, self.stored_weapon_info[ self.laststandpistol ].total_amt );
  2506.             self.stored_weapon_info[ self.laststandpistol ].given_amt = self.stored_weapon_info[ self.laststandpistol ].total_amt;
  2507.         }
  2508.         self SetWeaponAmmoStock( self.laststandpistol, 0 );
  2509.     }
  2510.     else
  2511.     {
  2512.         if ( self.stored_weapon_info[ self.laststandpistol ].stock_amt >= doubleclip )
  2513.         {
  2514.             self SetWeaponAmmoStock( self.laststandpistol, doubleclip );
  2515.             self.stored_weapon_info[ self.laststandpistol ].given_amt = doubleclip + self.stored_weapon_info[ self.laststandpistol ].clip_amt + self.stored_weapon_info[ self.laststandpistol ].left_clip_amt;
  2516.         }
  2517.         else
  2518.         {
  2519.             self SetWeaponAmmoStock( self.laststandpistol, self.stored_weapon_info[ self.laststandpistol ].stock_amt );
  2520.             self.stored_weapon_info[ self.laststandpistol ].given_amt = self.stored_weapon_info[ self.laststandpistol ].total_amt;
  2521.         }
  2522.     }
  2523.    
  2524.     self SwitchToWeapon( self.laststandpistol );
  2525. }
  2526.  
  2527. // ww: make sure the player has the best pistol when they go in to last stand
  2528. last_stand_best_pistol()
  2529. {
  2530.     pistol_array = [];
  2531.  
  2532.     current_weapons = self GetWeaponsListPrimaries();
  2533.    
  2534.     for( i = 0; i < current_weapons.size; i++ )
  2535.     {
  2536.         // make sure the weapon is a pistol
  2537.         if( WeaponClass( current_weapons[i] ) == "pistol" )
  2538.         {
  2539.             if (  (current_weapons[i] != "m1911_zm" && !flag("solo_game") )  || (!flag("solo_game") && current_weapons[i] != "m1911_upgraded_zm" ))
  2540.             {
  2541.                
  2542.                 if ( self GetAmmoCount( current_weapons[i] ) <= 0 )
  2543.                 {
  2544.                     continue;
  2545.                 }
  2546.             }
  2547.  
  2548.             pistol_array_index = pistol_array.size; // set up the spot in the array
  2549.             pistol_array[ pistol_array_index ] = SpawnStruct(); // struct to store info on
  2550.            
  2551.             pistol_array[ pistol_array_index ].gun = current_weapons[i];
  2552.             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
  2553.            
  2554.             // compare the current weapon to the level.pistol_values to see what the value is
  2555.             for( j = 0; j < level.pistol_values.size; j++ )
  2556.             {
  2557.                 if( level.pistol_values[j] == current_weapons[i] )
  2558.                 {
  2559.                     pistol_array[ pistol_array_index ].value = j;
  2560.                     break;
  2561.                 }
  2562.             }
  2563.         }
  2564.     }
  2565.    
  2566.     self.laststandpistol = last_stand_compare_pistols( pistol_array );
  2567. }
  2568.  
  2569. // ww: compares the array passed in for the highest valued pistol
  2570. last_stand_compare_pistols( struct_array )
  2571. {
  2572.     if( !IsArray( struct_array ) || struct_array.size <= 0 )
  2573.     {
  2574.         self.hadpistol = false;
  2575.        
  2576.         //array will be empty if the pistol had no ammo...so lets see if the player had the pistol
  2577.         if(isDefined(self.stored_weapon_info))
  2578.         {
  2579.             stored_weapon_info = GetArrayKeys( self.stored_weapon_info );
  2580.             for( j = 0; j < stored_weapon_info.size; j++ )
  2581.             {
  2582.                 if( stored_weapon_info[ j ] == level.laststandpistol)
  2583.                 {
  2584.                     self.hadpistol = true;
  2585.                 }
  2586.             }
  2587.         }
  2588.                
  2589.         return level.laststandpistol; // nothing in the array then give the level last stand pistol
  2590.     }
  2591.    
  2592.     highest_score_pistol = struct_array[0]; // first time through give the first one to the highest score
  2593.  
  2594.     for( i = 1; i < struct_array.size; i++ )
  2595.     {
  2596.         if( struct_array[i].value > highest_score_pistol.value )
  2597.         {
  2598.             highest_score_pistol = struct_array[i];
  2599.         }
  2600.     }
  2601.  
  2602.     if( flag( "solo_game" ) )
  2603.     {
  2604.         self._special_solo_pistol_swap = 0; // ww: this way the weapon knows to pack texture when given
  2605.         if( highest_score_pistol.value <= 4 )
  2606.         {
  2607.             self.hadpistol = false;
  2608.             self._special_solo_pistol_swap = 1;
  2609.             return level.laststandpistol; // ww: if it scores too low the player gets the 1911 upgraded
  2610.         }
  2611.         else
  2612.         {
  2613.             return highest_score_pistol.gun; // ww: gun is high in ranking and won't be replaced
  2614.         }
  2615.     }
  2616.     else // ww: happens when not in solo
  2617.     {
  2618.         return highest_score_pistol.gun;
  2619.     }
  2620.  
  2621. }
  2622.  
  2623. // ww: override function for saving player pistol ammo count
  2624. last_stand_save_pistol_ammo()
  2625. {
  2626.     weapon_inventory = self GetWeaponsList();
  2627.     self.stored_weapon_info = [];
  2628.  
  2629.     for( i = 0; i < weapon_inventory.size; i++ )
  2630.     {
  2631.         weapon = weapon_inventory[i];
  2632.  
  2633.         if ( WeaponClass( weapon ) == "pistol" )
  2634.         {
  2635.             self.stored_weapon_info[ weapon ] = SpawnStruct();
  2636.             self.stored_weapon_info[ weapon ].clip_amt = self GetWeaponAmmoClip( weapon );
  2637.             self.stored_weapon_info[ weapon ].left_clip_amt = 0;
  2638.             dual_wield_name = WeaponDualWieldWeaponName( weapon );
  2639.             if ( "none" != dual_wield_name )
  2640.             {
  2641.                 self.stored_weapon_info[ weapon ].left_clip_amt = self GetWeaponAmmoClip( dual_wield_name );
  2642.             }
  2643.             self.stored_weapon_info[ weapon ].stock_amt = self GetWeaponAmmoStock( weapon );
  2644.             self.stored_weapon_info[ weapon ].total_amt = self.stored_weapon_info[ weapon ].clip_amt + self.stored_weapon_info[ weapon ].left_clip_amt + self.stored_weapon_info[ weapon ].stock_amt;
  2645.             self.stored_weapon_info[ weapon ].given_amt = 0;
  2646.         }
  2647.     }
  2648.    
  2649.     self last_stand_best_pistol();
  2650. }
  2651.  
  2652. // ww: override to restore the player's pistol ammo after being picked up
  2653. last_stand_restore_pistol_ammo()
  2654. {
  2655.     self.weapon_taken_by_losing_specialty_additionalprimaryweapon = undefined;
  2656.  
  2657.     if( !IsDefined( self.stored_weapon_info ) )
  2658.     {
  2659.         return;
  2660.     }
  2661.    
  2662.     weapon_inventory = self GetWeaponsList();
  2663.     weapon_to_restore = GetArrayKeys( self.stored_weapon_info );
  2664.    
  2665.     for( i = 0; i < weapon_inventory.size; i++ )
  2666.     {
  2667.         weapon = weapon_inventory[i];
  2668.  
  2669.         if ( weapon != self.laststandpistol )
  2670.         {
  2671.             continue;
  2672.         }
  2673.  
  2674.         for( j = 0; j < weapon_to_restore.size; j++ )
  2675.         {
  2676.             check_weapon = weapon_to_restore[j];
  2677.            
  2678.             if( weapon == check_weapon )
  2679.             {
  2680.                 dual_wield_name = WeaponDualWieldWeaponName( weapon_to_restore[j] );
  2681.                 if ( weapon != "m1911_zm" )
  2682.                 {
  2683.                     last_clip = self GetWeaponAmmoClip( weapon );
  2684.                     last_left_clip = 0;
  2685.                     if ( "none" != dual_wield_name )
  2686.                     {
  2687.                         last_left_clip = self GetWeaponAmmoClip( dual_wield_name );
  2688.                     }
  2689.                     last_stock = self GetWeaponAmmoStock( weapon );
  2690.                     last_total = last_clip + last_left_clip + last_stock;
  2691.  
  2692.                     used_amt = self.stored_weapon_info[ weapon ].given_amt - last_total;
  2693.  
  2694.                     if ( used_amt >= self.stored_weapon_info[ weapon ].stock_amt )
  2695.                     {
  2696.                         used_amt -= self.stored_weapon_info[ weapon ].stock_amt;
  2697.                         self.stored_weapon_info[ weapon ].stock_amt = 0;
  2698.  
  2699.                         self.stored_weapon_info[ weapon ].clip_amt -= used_amt;
  2700.                         if ( self.stored_weapon_info[ weapon ].clip_amt < 0 )
  2701.                         {
  2702.                             self.stored_weapon_info[ weapon ].clip_amt = 0;
  2703.                         }
  2704.                     }
  2705.                     else
  2706.                     {
  2707.                         new_stock_amt = self.stored_weapon_info[ weapon ].stock_amt - used_amt;
  2708.                         if ( new_stock_amt < self.stored_weapon_info[ weapon ].stock_amt )
  2709.                         {
  2710.                             self.stored_weapon_info[ weapon ].stock_amt = new_stock_amt;
  2711.                         }
  2712.                     }
  2713.                 }
  2714.  
  2715.                 self SetWeaponAmmoClip( weapon_to_restore[j], self.stored_weapon_info[ weapon_to_restore[j] ].clip_amt );
  2716.                 if ( "none" != dual_wield_name )
  2717.                 {
  2718.                     self SetWeaponAmmoClip( dual_wield_name , self.stored_weapon_info[ weapon_to_restore[j] ].left_clip_amt );
  2719.                 }
  2720.                 self SetWeaponAmmoStock( weapon_to_restore[j], self.stored_weapon_info[ weapon_to_restore[j] ].stock_amt );
  2721.                 break;
  2722.             }
  2723.         }
  2724.     }
  2725. }
  2726.  
  2727. // ww: changes the last stand pistol to the upgraded 1911s if it is solo
  2728. zombiemode_solo_last_stand_pistol()
  2729. {
  2730.     level.laststandpistol = "m1911_upgraded_zm";
  2731. }
  2732.  
  2733. // ww: zeros out the player's grenades until they revive
  2734. last_stand_grenade_save_and_return()
  2735. {
  2736.     self endon( "death" );
  2737.    
  2738.     lethal_nade_amt = 0;
  2739.     has_lethal_nade = false;
  2740.     tactical_nade_amt = 0;
  2741.     has_tactical_nade = false;
  2742.    
  2743.     // figure out which nades this player has
  2744.     weapons_on_player = self GetWeaponsList();
  2745.     for ( i = 0; i < weapons_on_player.size; i++ )
  2746.     {
  2747.         if ( self is_player_lethal_grenade( weapons_on_player[i] ) )
  2748.         {
  2749.             has_lethal_nade = true;
  2750.             lethal_nade_amt = self GetWeaponAmmoClip( self get_player_lethal_grenade() );
  2751.             self SetWeaponAmmoClip( self get_player_lethal_grenade(), 0 );
  2752.             self TakeWeapon( self get_player_lethal_grenade() );
  2753.         }
  2754.         else if ( self is_player_tactical_grenade( weapons_on_player[i] ) )
  2755.         {
  2756.             has_tactical_nade = true;
  2757.             tactical_nade_amt = self GetWeaponAmmoClip( self get_player_tactical_grenade() );
  2758.             self SetWeaponAmmoClip( self get_player_tactical_grenade(), 0 );
  2759.             self TakeWeapon( self get_player_tactical_grenade() );
  2760.         }
  2761.     }
  2762.    
  2763.     self waittill( "player_revived" );
  2764.    
  2765.     if ( has_lethal_nade )
  2766.     {
  2767.         self GiveWeapon( self get_player_lethal_grenade() );
  2768.         self SetWeaponAmmoClip( self get_player_lethal_grenade(), lethal_nade_amt );
  2769.     }
  2770.    
  2771.     if ( has_tactical_nade )
  2772.     {
  2773.         self GiveWeapon( self get_player_tactical_grenade() );
  2774.         self SetWeaponAmmoClip( self get_player_tactical_grenade(), tactical_nade_amt );
  2775.     }
  2776. }
  2777.  
  2778. spectators_respawn()
  2779. {
  2780.     level endon( "between_round_over" );
  2781.  
  2782.     if( !IsDefined( level.zombie_vars["spectators_respawn"] ) || !level.zombie_vars["spectators_respawn"] )
  2783.     {
  2784.         return;
  2785.     }
  2786.  
  2787.     if( !IsDefined( level.custom_spawnPlayer ) )
  2788.     {
  2789.         // Custom spawn call for when they respawn from spectator
  2790.         level.custom_spawnPlayer = ::spectator_respawn;
  2791.     }
  2792.  
  2793.     while( 1 )
  2794.     {
  2795.         players = get_players();
  2796.         for( i = 0; i < players.size; i++ )
  2797.         {
  2798.             if( players[i].sessionstate == "spectator" )
  2799.             {
  2800.                 players[i] [[level.spawnPlayer]]();
  2801.                 if (isDefined(level.script) && level.round_number > 6 && players[i].score < 1500)
  2802.                 {
  2803.                     players[i].old_score = players[i].score;
  2804.                     players[i].score = 1500;
  2805.                     players[i] maps\_zombiemode_score::set_player_score_hud();
  2806.                 }
  2807.             }
  2808.         }
  2809.  
  2810.         wait( 1 );
  2811.     }
  2812. }
  2813.  
  2814. spectator_respawn()
  2815. {
  2816.     println( "*************************Respawn Spectator***" );
  2817.     assert( IsDefined( self.spectator_respawn ) );
  2818.  
  2819.     origin = self.spectator_respawn.origin;
  2820.     angles = self.spectator_respawn.angles;
  2821.  
  2822.     self setSpectatePermissions( false );
  2823.  
  2824.     new_origin = undefined;
  2825.    
  2826.     if ( isdefined( level.check_valid_spawn_override ) )
  2827.     {
  2828.         new_origin = [[ level.check_valid_spawn_override ]]( self );
  2829.     }
  2830.  
  2831.     if ( !isdefined( new_origin ) )
  2832.     {
  2833.         new_origin = check_for_valid_spawn_near_team( self );
  2834.     }
  2835.  
  2836.     if( IsDefined( new_origin ) )
  2837.     {
  2838.         self Spawn( new_origin, angles );
  2839.     }
  2840.     else
  2841.     {
  2842.         self Spawn( origin, angles );
  2843.     }
  2844.  
  2845.  
  2846. /*  we are not currently supporting the shared screen tech
  2847.     if( IsSplitScreen() )
  2848.     {
  2849.         last_alive = undefined;
  2850.         players = get_players();
  2851.  
  2852.         for( i = 0; i < players.size; i++ )
  2853.         {
  2854.             if( !players[i].is_zombie )
  2855.             {
  2856.                 last_alive = players[i];
  2857.             }
  2858.         }
  2859.  
  2860.         share_screen( last_alive, false );
  2861.     }
  2862. */
  2863.  
  2864.     if ( IsDefined( self get_player_placeable_mine() ) )
  2865.     {
  2866.         self TakeWeapon( self get_player_placeable_mine() );
  2867.         self set_player_placeable_mine( undefined );
  2868.     }
  2869.  
  2870.     self maps\_zombiemode_equipment::equipment_take();
  2871.  
  2872.     self.is_burning = undefined;
  2873.     self.abilities = [];
  2874.  
  2875.     // The check_for_level_end looks for this
  2876.     self.is_zombie = false;
  2877.     self.ignoreme = false;
  2878.  
  2879.     setClientSysState("lsm", "0", self);    // Notify client last stand ended.
  2880.     self RevivePlayer();
  2881.  
  2882.     self notify( "spawned_player" );
  2883.  
  2884.     if(IsDefined(level._zombiemode_post_respawn_callback))
  2885.     {
  2886.         self thread [[level._zombiemode_post_respawn_callback]]();
  2887.     }
  2888.  
  2889.     // Penalize the player when we respawn, since he 'died'
  2890.     self maps\_zombiemode_score::player_reduce_points( "died" );
  2891.    
  2892.     //DCS: make bowie & claymore trigger available again.
  2893.     bowie_triggers = GetEntArray( "bowie_upgrade", "targetname" );
  2894.     // ww: player needs to reset trigger knowledge without claiming full ownership
  2895.     self._bowie_zm_equipped = undefined;
  2896.     players = get_players();
  2897.     for( i = 0; i < bowie_triggers.size; i++ )
  2898.     {
  2899.         bowie_triggers[i] SetVisibleToAll();
  2900.         // check the player to see if he has the bowie, if they do trigger goes invisible
  2901.         for( j = 0; j < players.size; j++ )
  2902.         {
  2903.             if( IsDefined( players[j]._bowie_zm_equipped ) && players[j]._bowie_zm_equipped == 1 )
  2904.             {
  2905.                 bowie_triggers[i] SetInvisibleToPlayer( players[j] );
  2906.             }
  2907.         }
  2908.     }
  2909.    
  2910.     sickle_triggers = GetEntArray( "sickle_upgrade", "targetname" );
  2911.     // ww: player needs to reset trigger knowledge without claiming full ownership
  2912.     self._sickle_zm_equipped = undefined;
  2913.     players = get_players();
  2914.     for( i = 0; i < sickle_triggers.size; i++ )
  2915.     {
  2916.         sickle_triggers[i] SetVisibleToAll();
  2917.         // check the player to see if he has the sickle, if they do trigger goes invisible
  2918.         for( j = 0; j < players.size; j++ )
  2919.         {
  2920.             if( IsDefined( players[j]._sickle_zm_equipped ) && players[j]._sickle_zm_equipped == 1 )
  2921.             {
  2922.                 sickle_triggers[i] SetInvisibleToPlayer( players[j] );
  2923.             }
  2924.         }
  2925.     }
  2926.  
  2927.     // ww: inside _zombiemode_claymore the claymore triggers are fixed for players who haven't bought them
  2928.     // to see them after someone respawns from bleedout
  2929.     // 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
  2930.     // unless a bug comes through on it
  2931.     claymore_triggers = getentarray("claymore_purchase","targetname");
  2932.     for(i = 0; i < claymore_triggers.size; i++)
  2933.     {
  2934.         claymore_triggers[i] SetVisibleToPlayer(self);
  2935.         claymore_triggers[i].claymores_triggered = false;      
  2936.     }  
  2937.  
  2938.     self thread player_zombie_breadcrumb();
  2939.  
  2940.     return true;
  2941. }
  2942.  
  2943. check_for_valid_spawn_near_team( revivee )
  2944. {
  2945.  
  2946.     players = get_players();
  2947.     spawn_points = getstructarray("player_respawn_point", "targetname");
  2948.     closest_group = undefined;
  2949.     closest_distance = 100000000;
  2950.     backup_group = undefined;
  2951.     backup_distance = 100000000;
  2952.  
  2953.     if( spawn_points.size == 0 )
  2954.         return undefined;
  2955.  
  2956.     // Look for the closest group that is within the specified ideal distances
  2957.     //  If we can't find one within a valid area, use the closest unlocked group.
  2958.     for( i = 0; i < players.size; i++ )
  2959.     {
  2960.         if( is_player_valid( players[i] ) )
  2961.         {
  2962.             for( j = 0 ; j < spawn_points.size; j++ )
  2963.             {
  2964.                 if( isdefined(spawn_points[i].script_int) )
  2965.                     ideal_distance = spawn_points[i].script_int;
  2966.                 else
  2967.                     ideal_distance = 1000;
  2968.  
  2969.                 if ( spawn_points[j].locked == false )
  2970.                 {
  2971.                     distance = DistanceSquared( players[i].origin, spawn_points[j].origin );
  2972.                     if( distance < ( ideal_distance * ideal_distance ) )
  2973.                     {
  2974.                         if ( distance < closest_distance )
  2975.                         {
  2976.                             closest_distance = distance;
  2977.                             closest_group = j;
  2978.                         }
  2979.                     }
  2980.                     else
  2981.                     {
  2982.                         if ( distance < backup_distance )
  2983.                         {
  2984.                             backup_group = j;
  2985.                             backup_distance = distance;
  2986.                         }
  2987.                     }
  2988.                 }
  2989.             }
  2990.         }
  2991.         //  If we don't have a closest_group, let's use the backup
  2992.         if ( !IsDefined( closest_group ) )
  2993.         {
  2994.             closest_group = backup_group;
  2995.         }
  2996.  
  2997.         if ( IsDefined( closest_group ) )
  2998.         {
  2999.             spawn_array = getstructarray( spawn_points[closest_group].target, "targetname" );
  3000.  
  3001.             for( k = 0; k < spawn_array.size; k++ )
  3002.             {
  3003.                 if( spawn_array[k].script_int == (revivee.entity_num + 1) )
  3004.                 {
  3005.                     return spawn_array[k].origin;
  3006.                 }
  3007.             }  
  3008.  
  3009.             return spawn_array[0].origin;
  3010.         }
  3011.     }
  3012.  
  3013.     return undefined;
  3014.  
  3015. }
  3016.  
  3017.  
  3018. get_players_on_team(exclude)
  3019. {
  3020.  
  3021.     teammates = [];
  3022.  
  3023.     players = get_players();
  3024.     for(i=0;i<players.size;i++)
  3025.     {      
  3026.         //check to see if other players on your team are alive and not waiting to be revived
  3027.         if(players[i].spawn_side == self.spawn_side && !isDefined(players[i].revivetrigger) && players[i] != exclude )
  3028.         {
  3029.             teammates[teammates.size] = players[i];
  3030.         }
  3031.     }
  3032.  
  3033.     return teammates;
  3034. }
  3035.  
  3036.  
  3037.  
  3038. get_safe_breadcrumb_pos( player )
  3039. {
  3040.     players = get_players();
  3041.     valid_players = [];
  3042.  
  3043.     min_dist = 150 * 150;
  3044.     for( i = 0; i < players.size; i++ )
  3045.     {
  3046.         if( !is_player_valid( players[i] ) )
  3047.         {
  3048.             continue;
  3049.         }
  3050.  
  3051.         valid_players[valid_players.size] = players[i];
  3052.     }
  3053.  
  3054.     for( i = 0; i < valid_players.size; i++ )
  3055.     {
  3056.         count = 0;
  3057.         for( q = 1; q < player.zombie_breadcrumbs.size; q++ )
  3058.         {
  3059.             if( DistanceSquared( player.zombie_breadcrumbs[q], valid_players[i].origin ) < min_dist )
  3060.             {
  3061.                 continue;
  3062.             }
  3063.            
  3064.             count++;
  3065.             if( count == valid_players.size )
  3066.             {
  3067.                 return player.zombie_breadcrumbs[q];
  3068.             }
  3069.         }
  3070.     }
  3071.  
  3072.     return undefined;
  3073. }
  3074.  
  3075. default_max_zombie_func( max_num )
  3076. {
  3077.     max = max_num;
  3078.  
  3079.     if ( level.first_round )
  3080.     {
  3081.         max = int( max_num * 0.25 );   
  3082.     }
  3083.     else if (level.round_number < 3)
  3084.     {
  3085.         max = int( max_num * 0.3 );
  3086.     }
  3087.     else if (level.round_number < 4)
  3088.     {
  3089.         max = int( max_num * 0.5 );
  3090.     }
  3091.     else if (level.round_number < 5)
  3092.     {
  3093.         max = int( max_num * 0.7 );
  3094.     }
  3095.     else if (level.round_number < 6)
  3096.     {
  3097.         max = int( max_num * 0.9 );
  3098.     }
  3099.    
  3100.     return max;
  3101. }
  3102.  
  3103. round_spawning()
  3104. {
  3105.     level endon( "intermission" );
  3106.     level endon( "end_of_round" );
  3107.     level endon( "restart_round" );
  3108. /#
  3109.     level endon( "kill_round" );
  3110. #/
  3111.  
  3112.     if( level.intermission )
  3113.     {
  3114.         return;
  3115.     }
  3116.  
  3117.     if( level.enemy_spawns.size < 1 )
  3118.     {
  3119.         ASSERTMSG( "No active spawners in the map.  Check to see if the zone is active and if it's pointing to spawners." );
  3120.         return;
  3121.     }
  3122.  
  3123. /#
  3124.     if ( GetDvarInt( #"zombie_cheat" ) == 2 || GetDvarInt( #"zombie_cheat" ) >= 4 )
  3125.     {
  3126.         return;
  3127.     }
  3128. #/
  3129.  
  3130.     ai_calculate_health( level.round_number );
  3131.  
  3132.     count = 0;
  3133.  
  3134.     //CODER MOD: TOMMY K
  3135.     players = get_players();
  3136.     for( i = 0; i < players.size; i++ )
  3137.     {
  3138.         players[i].zombification_time = 0;
  3139.     }
  3140.  
  3141.     max = level.zombie_vars["zombie_max_ai"];
  3142.  
  3143.     multiplier = level.round_number / 5;
  3144.     if( multiplier < 1 )
  3145.     {
  3146.         multiplier = 1;
  3147.     }
  3148.  
  3149.     // After round 10, exponentially have more AI attack the player
  3150.     if( level.round_number >= 10 )
  3151.     {
  3152.         multiplier *= level.round_number * 0.15;
  3153.     }
  3154.  
  3155.     player_num = get_players().size;
  3156.  
  3157.     if( player_num == 1 )
  3158.     {
  3159.         max += int( ( 0.5 * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
  3160.     }
  3161.     else
  3162.     {
  3163.         max += int( ( ( player_num - 1 ) * level.zombie_vars["zombie_ai_per_player"] ) * multiplier );
  3164.     }
  3165.  
  3166.     if( !isDefined( level.max_zombie_func ) )
  3167.     {
  3168.         level.max_zombie_func = ::default_max_zombie_func;
  3169.     }
  3170.  
  3171.     // Now set the total for the new round, except when it's already been set by the
  3172.     //  kill counter.
  3173.     if ( !(IsDefined( level.kill_counter_hud ) && level.zombie_total > 0) )
  3174.     {
  3175.         level.zombie_total = [[ level.max_zombie_func ]]( max );
  3176.     }
  3177.  
  3178.     if ( IsDefined( level.zombie_total_set_func ) )
  3179.     {
  3180.         level thread [[ level.zombie_total_set_func ]]();
  3181.     }
  3182.  
  3183.     if ( level.round_number < 10 )
  3184.     {
  3185.         level thread zombie_speed_up();
  3186.     }
  3187.  
  3188.     mixed_spawns = 0;   // Number of mixed spawns this round.  Currently means number of dogs in a mixed round
  3189.  
  3190.     // DEBUG HACK: 
  3191.     //max = 1;
  3192.     old_spawn = undefined;
  3193. //  while( level.zombie_total > 0 )
  3194.     while( 1 )
  3195.     {
  3196.         while( get_enemy_count() >= level.zombie_ai_limit || level.zombie_total <= 0 )
  3197.         {
  3198.             wait( 0.1 );
  3199.         }
  3200.  
  3201.         // added ability to pause zombie spawning
  3202.         if ( !flag("spawn_zombies" ) )
  3203.         {
  3204.             flag_wait( "spawn_zombies" );
  3205.         }
  3206.  
  3207.         spawn_point = level.enemy_spawns[RandomInt( level.enemy_spawns.size )];
  3208.  
  3209.         if( !IsDefined( old_spawn ) )
  3210.         {
  3211.                 old_spawn = spawn_point;
  3212.         }
  3213.         else if( Spawn_point == old_spawn )
  3214.         {
  3215.                 spawn_point = level.enemy_spawns[RandomInt( level.enemy_spawns.size )];
  3216.         }
  3217.         old_spawn = spawn_point;
  3218.  
  3219.     //  iPrintLn(spawn_point.targetname + " " + level.zombie_vars["zombie_spawn_delay"]);
  3220.  
  3221.         // MM Mix in dog spawns...
  3222.         if ( IsDefined( level.mixed_rounds_enabled ) && level.mixed_rounds_enabled == 1 )
  3223.         {
  3224.             spawn_dog = false;
  3225.             if ( level.round_number > 30 )
  3226.             {
  3227.                 if ( RandomInt(100) < 3 )
  3228.                 {
  3229.                     spawn_dog = true;
  3230.                 }
  3231.             }
  3232.             else if ( level.round_number > 25 && mixed_spawns < 3 )
  3233.             {
  3234.                 if ( RandomInt(100) < 2 )
  3235.                 {
  3236.                     spawn_dog = true;
  3237.                 }
  3238.             }
  3239.             else if ( level.round_number > 20 && mixed_spawns < 2 )
  3240.             {
  3241.                 if ( RandomInt(100) < 2 )
  3242.                 {
  3243.                     spawn_dog = true;
  3244.                 }
  3245.             }
  3246.             else if ( level.round_number > 15 && mixed_spawns < 1 )
  3247.             {
  3248.                 if ( RandomInt(100) < 1 )
  3249.                 {
  3250.                     spawn_dog = true;
  3251.                 }
  3252.             }
  3253.            
  3254.             if ( spawn_dog )
  3255.             {
  3256.                 keys = GetArrayKeys( level.zones );
  3257.                 for ( i=0; i<keys.size; i++ )
  3258.                 {
  3259.                     if ( level.zones[ keys[i] ].is_occupied )
  3260.                     {
  3261.                         akeys = GetArrayKeys( level.zones[ keys[i] ].adjacent_zones );
  3262.                         for ( k=0; k<akeys.size; k++ )
  3263.                         {
  3264.                             if ( level.zones[ akeys[k] ].is_active &&
  3265.                                  !level.zones[ akeys[k] ].is_occupied &&
  3266.                                  level.zones[ akeys[k] ].dog_locations.size > 0 )
  3267.                             {
  3268.                                 maps\_zombiemode_ai_dogs::special_dog_spawn( undefined, 1 );
  3269.                                 level.zombie_total--;
  3270.                                 wait_network_frame();
  3271.                             }
  3272.                         }
  3273.                     }
  3274.                 }
  3275.             }
  3276.         }
  3277.  
  3278.         ai = spawn_zombie( spawn_point );
  3279.         if( IsDefined( ai ) )
  3280.         {
  3281.             level.zombie_total--;
  3282.             ai thread round_spawn_failsafe();
  3283.             count++;
  3284.         }
  3285.  
  3286.         wait( level.zombie_vars["zombie_spawn_delay"] );
  3287.         wait_network_frame();
  3288.     }
  3289. }
  3290.  
  3291. //
  3292. //  Make the last few zombies run
  3293. //
  3294. zombie_speed_up()
  3295. {
  3296.     if( level.round_number <= 3 )
  3297.     {
  3298.         return;
  3299.     }
  3300.  
  3301.     level endon( "intermission" );
  3302.     level endon( "end_of_round" );
  3303.     level endon( "restart_round" );
  3304. /#
  3305.     level endon( "kill_round" );
  3306. #/
  3307.  
  3308.     // Wait until we've finished spawning
  3309.     while ( level.zombie_total > 4 )
  3310.     {
  3311.         wait( 2.0 );
  3312.     }
  3313.  
  3314.     // Now wait for these guys to get whittled down
  3315.     num_zombies = get_enemy_count();
  3316.     while( num_zombies > 3 )
  3317.     {
  3318.         wait( 2.0 );
  3319.  
  3320.         num_zombies = get_enemy_count();
  3321.     }
  3322.  
  3323.     zombies = GetAiSpeciesArray( "axis", "all" );
  3324.     while( zombies.size > 0 )
  3325.     {
  3326.         if( zombies.size == 1 && zombies[0].has_legs == true )
  3327.         {
  3328.             if ( isdefined( level.zombie_speed_up ) )
  3329.             {
  3330.                 zombies[0] thread [[ level.zombie_speed_up ]]();
  3331.                 break;
  3332.             }
  3333.             else
  3334.             {
  3335.                 var = randomintrange(1, 4);
  3336.                 zombies[0] set_run_anim( "sprint" + var );                      
  3337.                 zombies[0].run_combatanim = level.scr_anim[zombies[0].animname]["sprint" + var];
  3338.             }
  3339.         }
  3340.         wait(0.5);
  3341.         zombies = GetAiSpeciesArray( "axis", "all" );
  3342.     }
  3343. }
  3344.  
  3345. // TESTING: spawn one zombie at a time
  3346. round_spawning_test()
  3347. {
  3348.     while (true)
  3349.     {
  3350.         spawn_point = level.enemy_spawns[RandomInt( level.enemy_spawns.size )]; // grab a random spawner
  3351.  
  3352.         ai = spawn_zombie( spawn_point );
  3353.         ai waittill("death");
  3354.  
  3355.         wait 5;
  3356.     }
  3357. }
  3358.  
  3359.  
  3360. /////////////////////////////////////////////////////////
  3361.  
  3362. // round_text( text )
  3363. // {
  3364. //  if( level.first_round )
  3365. //  {
  3366. //      intro = true;
  3367. //  }
  3368. //  else
  3369. //  {
  3370. //      intro = false;
  3371. //  }
  3372. //
  3373. //  hud = create_simple_hud();
  3374. //  hud.horzAlign = "center";
  3375. //  hud.vertAlign = "middle";
  3376. //  hud.alignX = "center";
  3377. //  hud.alignY = "middle";
  3378. //  hud.y = -100;
  3379. //  hud.foreground = 1;
  3380. //  hud.fontscale = 16.0;
  3381. //  hud.alpha = 0;
  3382. //  hud.color = ( 1, 1, 1 );
  3383. //
  3384. //  hud SetText( text );
  3385. //  hud FadeOverTime( 1.5 );
  3386. //  hud.alpha = 1;
  3387. //  wait( 1.5 );
  3388. //
  3389. //  if( intro )
  3390. //  {
  3391. //      wait( 1 );
  3392. //      level notify( "intro_change_color" );
  3393. //  }
  3394. //
  3395. //  hud FadeOverTime( 3 );
  3396. //  //hud.color = ( 0.8, 0, 0 );
  3397. //  hud.color = ( 0.21, 0, 0 );
  3398. //  wait( 3 );
  3399. //
  3400. //  if( intro )
  3401. //  {
  3402. //      level waittill( "intro_hud_done" );
  3403. //  }
  3404. //
  3405. //  hud FadeOverTime( 1.5 );
  3406. //  hud.alpha = 0;
  3407. //  wait( 1.5 );
  3408. //  hud destroy();
  3409. // }
  3410.  
  3411.  
  3412. //  Allows the round to be paused.  Displays a countdown timer.
  3413. //
  3414. round_pause( delay )
  3415. {
  3416.     if ( !IsDefined( delay ) )
  3417.     {
  3418.         delay = 30;
  3419.     }
  3420.  
  3421.     level.countdown_hud = create_counter_hud();
  3422.     level.countdown_hud SetValue( delay );
  3423.     level.countdown_hud.color = ( 1, 1, 1 );
  3424.     level.countdown_hud.alpha = 1;
  3425.     level.countdown_hud FadeOverTime( 2.0 );
  3426.     wait( 2.0 );
  3427.  
  3428.     level.countdown_hud.color = ( 0.21, 0, 0 );
  3429.     level.countdown_hud FadeOverTime( 3.0 );
  3430.     wait(3);
  3431.  
  3432.     while (delay >= 1)
  3433.     {
  3434.         wait (1);
  3435.         delay--;
  3436.         level.countdown_hud SetValue( delay );
  3437.     }
  3438.  
  3439.     // Zero!  Play end sound
  3440.     players = GetPlayers();
  3441.     for (i=0; i<players.size; i++ )
  3442.     {
  3443.         players[i] playlocalsound( "zmb_perks_packa_ready" );
  3444.     }
  3445.  
  3446.     level.countdown_hud FadeOverTime( 1.0 );
  3447.     level.countdown_hud.color = (1,1,1);
  3448.     level.countdown_hud.alpha = 0;
  3449.     wait( 1.0 );
  3450.  
  3451.     level.countdown_hud destroy_hud();
  3452. }
  3453.  
  3454.  
  3455. //  Zombie spawning
  3456. //
  3457. round_start()
  3458. {
  3459.     if ( IsDefined(level.round_prestart_func) )
  3460.     {
  3461.         [[ level.round_prestart_func ]]();
  3462.     }
  3463.     else
  3464.     {
  3465.         wait( 2 );
  3466.     }
  3467.  
  3468.     level.zombie_health = level.zombie_vars["zombie_health_start"];
  3469.  
  3470.     // so players get init'ed with grenades
  3471.     players = get_players();
  3472.     for (i = 0; i < players.size; i++)
  3473.     {
  3474.         players[i] giveweapon( players[i] get_player_lethal_grenade() );   
  3475.         players[i] setweaponammoclip( players[i] get_player_lethal_grenade(), 0);
  3476.         players[i] SetClientDvars( "ammoCounterHide", "0",
  3477.                 "miniscoreboardhide", "0" );
  3478.         //players[i] thread maps\_zombiemode_ability::give_round1_abilities();
  3479.     }
  3480.  
  3481.     if( getDvarInt( #"scr_writeconfigstrings" ) == 1 )
  3482.     {
  3483.         wait(5);
  3484.         ExitLevel();
  3485.         return;
  3486.     }
  3487. //  if( isDefined(level.chests) && isDefined(level.chest_index) )
  3488. //  {
  3489. //      Objective_Add( 0, "active", "Mystery Box", level.chests[level.chest_index].chest_lid.origin, "minimap_icon_mystery_box" );
  3490. //  }
  3491.  
  3492.     if ( level.zombie_vars["game_start_delay"] > 0 )
  3493.     {
  3494.         round_pause( level.zombie_vars["game_start_delay"] );
  3495.     }
  3496.  
  3497.     flag_set( "begin_spawning" );
  3498.    
  3499.     //maps\_zombiemode_solo::init();
  3500.  
  3501.     level.chalk_hud1 = create_chalk_hud();
  3502. //  if( level.round_number >= 1 && level.round_number <= 5 )
  3503. //  {
  3504. //      level.chalk_hud1 SetShader( "hud_chalk_" + level.round_number, 64, 64 );
  3505. //  }
  3506. //  else if ( level.round_number >= 5 && level.round_number <= 10 )
  3507. //  {
  3508. //      level.chalk_hud1 SetShader( "hud_chalk_5", 64, 64 );
  3509. //  }
  3510.     level.chalk_hud2 = create_chalk_hud( 64 );
  3511.  
  3512.     //  level waittill( "introscreen_done" );
  3513.  
  3514.     if( !isDefined(level.round_spawn_func) )
  3515.     {
  3516.         level.round_spawn_func = ::round_spawning;
  3517.     }
  3518. /#
  3519.     if (GetDvarInt( #"zombie_rise_test") )
  3520.     {
  3521.         level.round_spawn_func = ::round_spawning_test;     // FOR TESTING, one zombie at a time, no round advancement
  3522.     }
  3523. #/
  3524.  
  3525.     if ( !isDefined(level.round_wait_func) )
  3526.     {
  3527.         level.round_wait_func = ::round_wait;
  3528.     }
  3529.  
  3530.     if ( !IsDefined(level.round_think_func) )
  3531.     {
  3532.         level.round_think_func = ::round_think;
  3533.     }
  3534.  
  3535.     if( level.mutators["mutator_fogMatch"] )
  3536.     {
  3537.         players = get_players();
  3538.         for( i = 0; i < players.size; i++ )
  3539.         {
  3540.             players[i] thread set_fog( 729.34, 971.99, 338.336, 398.623, 0.58, 0.60, 0.56, 3 );
  3541.         }
  3542.     }
  3543.  
  3544.     level thread [[ level.round_think_func ]]();
  3545. }
  3546.  
  3547.  
  3548. //
  3549. //
  3550. create_chalk_hud( x )
  3551. {
  3552.     if( !IsDefined( x ) )
  3553.     {
  3554.         x = 0;
  3555.     }
  3556.  
  3557.     hud = create_simple_hud();
  3558.     hud.alignX = "left";
  3559.     hud.alignY = "bottom";
  3560.     hud.horzAlign = "user_left";
  3561.     hud.vertAlign = "user_bottom";
  3562.     hud.color = ( 0.21, 0, 0 );
  3563.     hud.x = x;
  3564.     hud.y = -4;
  3565.     hud.alpha = 0;
  3566.     hud.fontscale = 32.0;
  3567.  
  3568.     hud SetShader( "hud_chalk_1", 64, 64 );
  3569.  
  3570.     return hud;
  3571. }
  3572.  
  3573.  
  3574. //
  3575. //
  3576. destroy_chalk_hud()
  3577. {
  3578.     if( isDefined( level.chalk_hud1 ) )
  3579.     {
  3580.         level.chalk_hud1 Destroy();
  3581.         level.chalk_hud1 = undefined;
  3582.     }
  3583.  
  3584.     if( isDefined( level.chalk_hud2 ) )
  3585.     {
  3586.         level.chalk_hud2 Destroy();
  3587.         level.chalk_hud2 = undefined;
  3588.     }
  3589. }
  3590.  
  3591.  
  3592. //
  3593. // Let's the players know that you need power to open these
  3594. play_door_dialog()
  3595. {
  3596.     level endon( "power_on" );
  3597.     self endon ("warning_dialog");
  3598.     timer = 0;
  3599.  
  3600.     while(1)
  3601.     {
  3602.         wait(0.05);
  3603.         players = get_players();
  3604.         for(i = 0; i < players.size; i++)
  3605.         {      
  3606.             dist = distancesquared(players[i].origin, self.origin );
  3607.             if(dist > 70*70)
  3608.             {
  3609.                 timer =0;
  3610.                 continue;
  3611.             }
  3612.             while(dist < 70*70 && timer < 3)
  3613.             {
  3614.                 wait(0.5);
  3615.                 timer++;
  3616.             }
  3617.             if(dist > 70*70 && timer >= 3)
  3618.             {
  3619.                 self playsound("door_deny");
  3620.                
  3621.                 players[i] maps\_zombiemode_audio::create_and_play_dialog( "general", "door_deny" );   
  3622.                 wait(3);               
  3623.                 self notify ("warning_dialog");
  3624.                 //iprintlnbold("warning_given");
  3625.             }
  3626.         }
  3627.     }
  3628. }
  3629.  
  3630. wait_until_first_player()
  3631. {
  3632.     players = get_players();
  3633.     if( !IsDefined( players[0] ) )
  3634.     {
  3635.         level waittill( "first_player_ready" );
  3636.     }
  3637. }
  3638.  
  3639. //
  3640. //  Set the current round number hud display
  3641. chalk_one_up()
  3642. {
  3643.     huds = [];
  3644.     huds[0] = level.chalk_hud1;
  3645.     huds[1] = level.chalk_hud2;
  3646.  
  3647.     // Hud1 shader
  3648.     if( level.round_number >= 1 && level.round_number <= 5 )
  3649.     {
  3650.         huds[0] SetShader( "hud_chalk_" + level.round_number, 64, 64 );
  3651.     }
  3652.     else if ( level.round_number >= 5 && level.round_number <= 10 )
  3653.     {
  3654.         huds[0] SetShader( "hud_chalk_5", 64, 64 );
  3655.     }
  3656.  
  3657.     // Hud2 shader
  3658.     if( level.round_number > 5 && level.round_number <= 10 )
  3659.     {
  3660.         huds[1] SetShader( "hud_chalk_" + ( level.round_number - 5 ), 64, 64 );
  3661.     }
  3662.  
  3663.     // Display value
  3664.     if ( IsDefined( level.chalk_override ) )
  3665.     {
  3666.         huds[0] SetText( level.chalk_override );
  3667.         huds[1] SetText( " " );
  3668.     }
  3669.     else if( level.round_number <= 5 )
  3670.     {
  3671.         huds[1] SetText( " " );
  3672.     }
  3673.     else if( level.round_number > 10 )
  3674.     {
  3675.         huds[0].fontscale = 32;
  3676.         huds[0] SetValue( level.round_number );
  3677.         huds[1] SetText( " " );
  3678.     }
  3679.  
  3680.     if(!IsDefined(level.doground_nomusic))
  3681.     {
  3682.         level.doground_nomusic = 0;
  3683.     }
  3684.     if( level.first_round )
  3685.     {
  3686.         intro = true;
  3687.         if( isdefined( level._custom_intro_vox ) )
  3688.         {
  3689.             level thread [[level._custom_intro_vox]]();
  3690.         }
  3691.         else
  3692.         {
  3693.             level thread play_level_start_vox_delayed();
  3694.         }
  3695.     }
  3696.     else
  3697.     {
  3698.         intro = false;
  3699.     }
  3700.    
  3701.     //Round Number Specific Lines
  3702.     if( level.round_number == 5 || level.round_number == 10 || level.round_number == 20 || level.round_number == 35 || level.round_number == 50 )
  3703.     {
  3704.         players = getplayers();
  3705.         rand = RandomIntRange(0,players.size);
  3706.         players[rand] thread maps\_zombiemode_audio::create_and_play_dialog( "general", "round_" + level.round_number );
  3707.     }
  3708.  
  3709.     round = undefined; 
  3710.     if( intro )
  3711.     {
  3712.         // Create "ROUND" hud text
  3713.         round = create_simple_hud();
  3714.         round.alignX = "center";
  3715.         round.alignY = "bottom";
  3716.         round.horzAlign = "user_center";
  3717.         round.vertAlign = "user_bottom";
  3718.         round.fontscale = 16;
  3719.         round.color = ( 1, 1, 1 );
  3720.         round.x = 0;
  3721.         round.y = -265;
  3722.         round.alpha = 0;
  3723.         round SetText( &"ZOMBIE_ROUND" );
  3724.  
  3725. //      huds[0] FadeOverTime( 0.05 );
  3726.         huds[0].color = ( 1, 1, 1 );
  3727.         huds[0].alpha = 0;
  3728.         huds[0].horzAlign = "user_center";
  3729.         huds[0].x = -5;
  3730.         huds[0].y = -200;
  3731.  
  3732.         huds[1] SetText( " " );
  3733.  
  3734.         // Fade in white
  3735.         round FadeOverTime( 1 );
  3736.         round.alpha = 1;
  3737.  
  3738.         huds[0] FadeOverTime( 1 );
  3739.         huds[0].alpha = 1;
  3740.  
  3741.         wait( 1 );
  3742.  
  3743.         // Fade to red
  3744.         round FadeOverTime( 2 );
  3745.         round.color = ( 0.21, 0, 0 );
  3746.  
  3747.         huds[0] FadeOverTime( 2 );
  3748.         huds[0].color = ( 0.21, 0, 0 );
  3749.         wait(2);
  3750.     }
  3751.     else
  3752.     {
  3753.         for ( i=0; i<huds.size; i++ )
  3754.         {
  3755.             huds[i] FadeOverTime( 0.5 );
  3756.             huds[i].alpha = 0;
  3757.         }
  3758.         wait( 0.5 );
  3759.     }
  3760.  
  3761. //  if( (level.round_number <= 5 || level.round_number >= 11) && IsDefined( level.chalk_hud2 ) )
  3762. //  {
  3763. //      huds[1] = undefined;
  3764. //  }
  3765. //  
  3766.     for ( i=0; i<huds.size; i++ )
  3767.     {
  3768.         huds[i] FadeOverTime( 2 );
  3769.         huds[i].alpha = 1;
  3770.     }
  3771.  
  3772.     if( intro )
  3773.     {
  3774.         wait( 3 );
  3775.  
  3776.         if( IsDefined( round ) )
  3777.         {
  3778.             round FadeOverTime( 1 );
  3779.             round.alpha = 0;
  3780.         }
  3781.  
  3782.         wait( 0.25 );
  3783.  
  3784.         level notify( "intro_hud_done" );
  3785.         huds[0] MoveOverTime( 1.75 );
  3786.         huds[0].horzAlign = "user_left";
  3787.         //      huds[0].x = 0;
  3788.         huds[0].y = -4;
  3789.         wait( 2 );
  3790.  
  3791.         round destroy_hud();
  3792.     }
  3793.     else
  3794.     {
  3795.         for ( i=0; i<huds.size; i++ )
  3796.         {
  3797.             huds[i].color = ( 1, 1, 1 );
  3798.         }
  3799.     }
  3800.  
  3801.     // Okay now wait just a bit to let the number set in
  3802.     if ( !intro )
  3803.     {
  3804.         wait( 2 );
  3805.  
  3806.         for ( i=0; i<huds.size; i++ )
  3807.         {
  3808.             huds[i] FadeOverTime( 1 );
  3809.             huds[i].color = ( 0.21, 0, 0 );
  3810.         }
  3811.     }
  3812.    
  3813.     ReportMTU(level.round_number);  // In network debug instrumented builds, causes network spike report to generate.
  3814.  
  3815.     // Remove any override set since we're done with it
  3816.     if ( IsDefined( level.chalk_override ) )
  3817.     {
  3818.         level.chalk_override = undefined;
  3819.     }
  3820. }
  3821.  
  3822.  
  3823. //  Flash the round display at the end of the round
  3824. //
  3825. chalk_round_over()
  3826. {
  3827.     huds = [];
  3828.     huds[huds.size] = level.chalk_hud1;
  3829.     huds[huds.size] = level.chalk_hud2;
  3830.  
  3831.     if( level.round_number <= 5 || level.round_number > 10 )
  3832.     {
  3833.         level.chalk_hud2 SetText( " " );
  3834.     }
  3835.  
  3836.     time = level.zombie_vars["zombie_between_round_time"];
  3837.     if ( time > 3 )
  3838.     {
  3839.         time = time - 2;    // add this deduction back in at the bottom
  3840.     }
  3841.  
  3842.     for( i = 0; i < huds.size; i++ )
  3843.     {
  3844.         if( IsDefined( huds[i] ) )
  3845.         {
  3846.             huds[i] FadeOverTime( time * 0.25 );
  3847.             huds[i].color = ( 1, 1, 1 );
  3848.         }
  3849.     }
  3850.  
  3851.     // Pulse
  3852.     fade_time = 0.5;
  3853.     steps =  ( time * 0.5 ) / fade_time;
  3854.     for( q = 0; q < steps; q++ )
  3855.     {
  3856.         for( i = 0; i < huds.size; i++ )
  3857.         {
  3858.             if( !IsDefined( huds[i] ) )
  3859.             {
  3860.                 continue;
  3861.             }
  3862.  
  3863.             huds[i] FadeOverTime( fade_time );
  3864.             huds[i].alpha = 0;
  3865.         }
  3866.  
  3867.         wait( fade_time );
  3868.  
  3869.         for( i = 0; i < huds.size; i++ )
  3870.         {
  3871.             if( !IsDefined( huds[i] ) )
  3872.             {
  3873.                 continue;
  3874.             }
  3875.  
  3876.             huds[i] FadeOverTime( fade_time );
  3877.             huds[i].alpha = 1;     
  3878.         }
  3879.  
  3880.         wait( fade_time );
  3881.     }
  3882.  
  3883.     for( i = 0; i < huds.size; i++ )
  3884.     {
  3885.         if( !IsDefined( huds[i] ) )
  3886.         {
  3887.             continue;
  3888.         }
  3889.  
  3890.         huds[i] FadeOverTime( time * 0.25 );
  3891.         //      huds[i].color = ( 0.8, 0, 0 );
  3892.         huds[i].color = ( 0.21, 0, 0 );
  3893.         huds[i].alpha = 0;
  3894.     }
  3895.  
  3896.     wait ( 2.0 );
  3897. }
  3898.  
  3899. round_think()
  3900. {
  3901.     for( ;; )
  3902.     {
  3903.         //////////////////////////////////////////
  3904.         //designed by prod DT#36173
  3905.         maxreward = 50 * level.round_number;
  3906.         if ( maxreward > 500 )
  3907.             maxreward = 500;
  3908.         level.zombie_vars["rebuild_barrier_cap_per_round"] = maxreward;
  3909.         //////////////////////////////////////////
  3910.  
  3911.         level.pro_tips_start_time = GetTime();
  3912.         level.zombie_last_run_time = GetTime(); // Resets the last time a zombie ran
  3913.    
  3914.         level thread maps\_zombiemode_audio::change_zombie_music( "round_start" );
  3915.         chalk_one_up();
  3916.         //      round_text( &"ZOMBIE_ROUND_BEGIN" );
  3917.  
  3918.         maps\_zombiemode_powerups::powerup_round_start();
  3919.  
  3920.         players = get_players();
  3921.         array_thread( players, maps\_zombiemode_blockers::rebuild_barrier_reward_reset );
  3922.  
  3923.         //array_thread( players, maps\_zombiemode_ability::giveHardpointItems );
  3924.  
  3925.         level thread award_grenades_for_survivors();
  3926.  
  3927.         bbPrint( "zombie_rounds: round %d player_count %d", level.round_number, players.size );
  3928.  
  3929.         level.round_start_time = GetTime();
  3930.         level thread [[level.round_spawn_func]]();
  3931.  
  3932.         level notify( "start_of_round" );
  3933.  
  3934.         [[level.round_wait_func]]();
  3935.  
  3936.         level.first_round = false;
  3937.         level notify( "end_of_round" );
  3938.        
  3939.         level thread maps\_zombiemode_audio::change_zombie_music( "round_end" );
  3940.        
  3941.         UploadStats();
  3942.  
  3943.         if ( 1 != players.size )
  3944.         {
  3945.             level thread spectators_respawn();
  3946.             //level thread last_stand_revive();
  3947.         }
  3948.  
  3949.         //      round_text( &"ZOMBIE_ROUND_END" );
  3950.         level chalk_round_over();
  3951.  
  3952.         // here's the difficulty increase over time area
  3953.         timer = level.zombie_vars["zombie_spawn_delay"];
  3954.         if ( timer > 0.08 )
  3955.         {
  3956.             level.zombie_vars["zombie_spawn_delay"] = timer * 0.95;
  3957.         }
  3958.         else if ( timer < 0.08 )
  3959.         {
  3960.             level.zombie_vars["zombie_spawn_delay"] = 0.08;
  3961.         }
  3962.  
  3963.         //
  3964.         // Increase the zombie move speed
  3965.         level.zombie_move_speed = level.round_number * level.zombie_vars["zombie_move_speed_multiplier"];
  3966.  
  3967. //      iPrintlnBold( "End of Round " + level.round_number );
  3968. //      for ( i=0; i<level.team_pool.size; i++ )
  3969. //      {
  3970. //          iPrintlnBold( "Team Pool "+(i+1)+" score: ", level.team_pool[i].score_total );
  3971. //      }
  3972. //
  3973. //      players = get_players();
  3974. //      for ( p=0; p<players.size; p++ )
  3975. //      {
  3976. //          iPrintlnBold( "Total Player "+(p+1)+" score : "+ players[p].score_total );
  3977. //      }
  3978.  
  3979.         level.round_number++;
  3980.  
  3981.         level notify( "between_round_over" );
  3982.     }
  3983. }
  3984.  
  3985.  
  3986. award_grenades_for_survivors()
  3987. {
  3988.     players = get_players();
  3989.  
  3990.     for (i = 0; i < players.size; i++)
  3991.     {
  3992.         if (!players[i].is_zombie)
  3993.         {
  3994.             lethal_grenade = players[i] get_player_lethal_grenade();
  3995.             if( !players[i] HasWeapon( lethal_grenade ) )
  3996.             {
  3997.                 players[i] GiveWeapon( lethal_grenade );   
  3998.                 players[i] SetWeaponAmmoClip( lethal_grenade, 0 );
  3999.             }
  4000.  
  4001.             if ( players[i] GetFractionMaxAmmo( lethal_grenade ) < .25 )
  4002.             {
  4003.                 players[i] SetWeaponAmmoClip( lethal_grenade, 2 );
  4004.             }
  4005.             else if (players[i] GetFractionMaxAmmo( lethal_grenade ) < .5 )
  4006.             {
  4007.                 players[i] SetWeaponAmmoClip( lethal_grenade, 3 );
  4008.             }
  4009.             else
  4010.             {
  4011.                 players[i] SetWeaponAmmoClip( lethal_grenade, 4 );
  4012.             }
  4013.         }
  4014.     }
  4015. }
  4016.  
  4017. ai_calculate_health( round_number )
  4018. {
  4019.     level.zombie_health = level.zombie_vars["zombie_health_start"];
  4020.     for ( i=2; i<=round_number; i++ )
  4021.     {
  4022.         // After round 10, get exponentially harder
  4023.         if( i >= 10 )
  4024.         {
  4025.             level.zombie_health += Int( level.zombie_health * level.zombie_vars["zombie_health_increase_multiplier"] );
  4026.         }
  4027.         else
  4028.         {
  4029.             level.zombie_health = Int( level.zombie_health + level.zombie_vars["zombie_health_increase"] );
  4030.         }
  4031.     }
  4032. }
  4033.  
  4034. /#
  4035. round_spawn_failsafe_debug()
  4036. {
  4037.     level notify( "failsafe_debug_stop" );
  4038.     level endon( "failsafe_debug_stop" );
  4039.  
  4040.     start = GetTime();
  4041.     level.chunk_time = 0;
  4042.  
  4043.     while ( 1 )
  4044.     {
  4045.         level.failsafe_time = GetTime() - start;
  4046.  
  4047.         if ( isdefined( self.lastchunk_destroy_time ) )
  4048.         {
  4049.             level.chunk_time = GetTime() - self.lastchunk_destroy_time;
  4050.         }
  4051.         wait_network_frame();
  4052.     }
  4053. }
  4054. #/
  4055.  
  4056.  
  4057. //put the conditions in here which should
  4058. //cause the failsafe to reset
  4059. round_spawn_failsafe()
  4060. {
  4061.     self endon("death");//guy just died
  4062.  
  4063.     //////////////////////////////////////////////////////////////
  4064.     //FAILSAFE "hack shit"  DT#33203
  4065.     //////////////////////////////////////////////////////////////
  4066.     prevorigin = self.origin;
  4067.     while(1)
  4068.     {
  4069.         if( !level.zombie_vars["zombie_use_failsafe"] )
  4070.         {
  4071.             return;
  4072.         }
  4073.  
  4074.         if ( is_true( self.ignore_round_spawn_failsafe ) )
  4075.         {
  4076.             return;
  4077.         }
  4078.  
  4079.         wait( 30 );
  4080.  
  4081.         //if i've torn a board down in the last 8 seconds, just
  4082.         //wait 30 again.
  4083.         if ( isDefined(self.lastchunk_destroy_time) )
  4084.         {
  4085.             if ( (GetTime() - self.lastchunk_destroy_time) < 8000 )
  4086.                 continue;
  4087.         }
  4088.  
  4089.         //fell out of world
  4090.         if ( self.origin[2] < level.zombie_vars["below_world_check"] )
  4091.         {
  4092.             if(is_true(level.put_timed_out_zombies_back_in_queue ) && !flag("dog_round") )
  4093.             {
  4094.                 level.zombie_total++;  
  4095.             }          
  4096.             self dodamage( self.health + 100, (0,0,0) );               
  4097.             break;
  4098.         }
  4099.  
  4100.         //hasnt moved 24 inches in 30 seconds? 
  4101.         if ( DistanceSquared( self.origin, prevorigin ) < 576 )
  4102.         {
  4103.            
  4104.             //add this zombie back into the spawner queue to be re-spawned
  4105.             if(is_true(level.put_timed_out_zombies_back_in_queue ) && !flag("dog_round"))
  4106.             {
  4107.                 //only if they have crawled thru a window and then timed out
  4108.                 if(!self.ignoreall && !is_true(self.nuked) && !is_true(self.marked_for_death))
  4109.                 {
  4110.                     level.zombie_total++;  
  4111.                 }
  4112.             }
  4113.            
  4114.             //add this to the stats even tho he really didn't 'die'
  4115.             level.zombies_timeout_playspace++;
  4116.            
  4117.             // DEBUG HACK
  4118.             self dodamage( self.health + 100, (0,0,0) );
  4119.             break;
  4120.         }
  4121.  
  4122.         prevorigin = self.origin;
  4123.     }
  4124.     //////////////////////////////////////////////////////////////
  4125.     //END OF FAILSAFE "hack shit"
  4126.     //////////////////////////////////////////////////////////////
  4127. }
  4128.  
  4129. // Waits for the time and the ai to die
  4130. round_wait()
  4131. {
  4132. /#
  4133.     if (GetDvarInt( #"zombie_rise_test") )
  4134.     {
  4135.         level waittill("forever"); // TESTING: don't advance rounds
  4136.     }
  4137. #/
  4138.  
  4139. /#
  4140.     if ( GetDvarInt( #"zombie_cheat" ) == 2 || GetDvarInt( #"zombie_cheat" ) >= 4 )
  4141.     {
  4142.         level waittill("forever");
  4143.     }
  4144. #/
  4145.  
  4146.     wait( 1 );
  4147.  
  4148.     if( flag("dog_round" ) )
  4149.     {
  4150.         wait(7);
  4151.         while( level.dog_intermission )
  4152.         {
  4153.             wait(0.5);
  4154.         }
  4155.     }
  4156.     else
  4157.     {
  4158.         while( get_enemy_count() > 0 || level.zombie_total > 0 || level.intermission )
  4159.         {
  4160.             if( flag( "end_round_wait" ) )
  4161.             {
  4162.                 return;
  4163.             }
  4164.             wait( 1.0 );
  4165.         }
  4166.     }
  4167. }
  4168.  
  4169.  
  4170. is_friendly_fire_on()
  4171. {
  4172.     return level.mutators[ "mutator_friendlyFire" ];
  4173. }
  4174.  
  4175.  
  4176. can_revive( reviver )
  4177. {
  4178.     if( self has_powerup_weapon() )
  4179.     {
  4180.         return false;
  4181.     }
  4182.    
  4183.     return true;
  4184. }
  4185.  
  4186.  
  4187. zombify_player()
  4188. {
  4189.     self maps\_zombiemode_score::player_died_penalty();
  4190.  
  4191.     bbPrint( "zombie_playerdeaths: round %d playername %s deathtype died x %f y %f z %f", level.round_number, self.playername, self.origin );
  4192.  
  4193.     if ( IsDefined( level.deathcard_spawn_func ) )
  4194.     {
  4195.         self [[level.deathcard_spawn_func]]();
  4196.     }
  4197.  
  4198.     if( !IsDefined( level.zombie_vars["zombify_player"] ) || !level.zombie_vars["zombify_player"] )
  4199.     {
  4200.         if (!is_true(self.solo_respawn ))
  4201.         {
  4202.             self thread spawnSpectator();
  4203.         }
  4204.  
  4205.         return;
  4206.     }
  4207.  
  4208.     self.ignoreme = true;
  4209.     self.is_zombie = true;
  4210.     self.zombification_time = GetTime();
  4211.  
  4212.     self.team = "axis";
  4213.     self notify( "zombified" );
  4214.  
  4215.     if( IsDefined( self.revivetrigger ) )
  4216.     {
  4217.         self.revivetrigger Delete();
  4218.     }
  4219.     self.revivetrigger = undefined;
  4220.  
  4221.     self setMoveSpeedScale( 0.3 );
  4222.     self reviveplayer();
  4223.  
  4224.     self TakeAllWeapons();
  4225.     //self starttanning();
  4226.     self GiveWeapon( "zombie_melee", 0 );
  4227.     self SwitchToWeapon( "zombie_melee" );
  4228.     self DisableWeaponCycling();
  4229.     self DisableOffhandWeapons();
  4230.     self VisionSetNaked( "zombie_turned", 1 );
  4231.  
  4232.     maps\_utility::setClientSysState( "zombify", 1, self );     // Zombie grain goooo
  4233.  
  4234.     self thread maps\_zombiemode_spawner::zombie_eye_glow();
  4235.  
  4236.     // set up the ground ref ent
  4237.     self thread injured_walk();
  4238.     // allow for zombie attacks, but they lose points?
  4239.  
  4240.     self thread playerzombie_player_damage();
  4241.     self thread playerzombie_soundboard();
  4242. }
  4243.  
  4244. playerzombie_player_damage()
  4245. {
  4246.     self endon( "death" );
  4247.     self endon( "disconnect" );
  4248.  
  4249.     self thread playerzombie_infinite_health();  // manually keep regular health up
  4250.     self.zombiehealth = level.zombie_health;
  4251.  
  4252.     // enable PVP damage on this guy
  4253.     // self EnablePvPDamage();
  4254.  
  4255.     while( 1 )
  4256.     {
  4257.         self waittill( "damage", amount, attacker, directionVec, point, type );
  4258.  
  4259.         if( !IsDefined( attacker ) || !IsPlayer( attacker ) )
  4260.         {
  4261.             wait( 0.05 );
  4262.             continue;
  4263.         }
  4264.  
  4265.         self.zombiehealth -= amount;
  4266.  
  4267.         if( self.zombiehealth <= 0 )
  4268.         {
  4269.             // "down" the zombie
  4270.             self thread playerzombie_downed_state();
  4271.             self waittill( "playerzombie_downed_state_done" );
  4272.             self.zombiehealth = level.zombie_health;
  4273.         }
  4274.     }
  4275. }
  4276.  
  4277. playerzombie_downed_state()
  4278. {
  4279.     self endon( "death" );
  4280.     self endon( "disconnect" );
  4281.  
  4282.     downTime = 15;
  4283.  
  4284.     startTime = GetTime();
  4285.     endTime = startTime +( downTime * 1000 );
  4286.  
  4287.     self thread playerzombie_downed_hud();
  4288.  
  4289.     self.playerzombie_soundboard_disable = true;
  4290.     self thread maps\_zombiemode_spawner::zombie_eye_glow_stop();
  4291.     self DisableWeapons();
  4292.     self AllowStand( false );
  4293.     self AllowCrouch( false );
  4294.     self AllowProne( true );
  4295.  
  4296.     while( GetTime() < endTime )
  4297.     {
  4298.         wait( 0.05 );
  4299.     }
  4300.  
  4301.     self.playerzombie_soundboard_disable = false;
  4302.     self thread maps\_zombiemode_spawner::zombie_eye_glow();
  4303.     self EnableWeapons();
  4304.     self AllowStand( true );
  4305.     self AllowCrouch( false );
  4306.     self AllowProne( false );
  4307.  
  4308.     self notify( "playerzombie_downed_state_done" );
  4309. }
  4310.  
  4311. playerzombie_downed_hud()
  4312. {
  4313.     self endon( "death" );
  4314.     self endon( "disconnect" );
  4315.  
  4316.     text = NewClientHudElem( self );
  4317.     text.alignX = "center";
  4318.     text.alignY = "middle";
  4319.     text.horzAlign = "user_center";
  4320.     text.vertAlign = "user_bottom";
  4321.     text.foreground = true;
  4322.     text.font = "default";
  4323.     text.fontScale = 1.8;
  4324.     text.alpha = 0;
  4325.     text.color = ( 1.0, 1.0, 1.0 );
  4326.     text SetText( &"ZOMBIE_PLAYERZOMBIE_DOWNED" );
  4327.  
  4328.     text.y = -113;  
  4329.     if( IsSplitScreen() )
  4330.     {
  4331.         text.y = -137;
  4332.     }
  4333.  
  4334.     text FadeOverTime( 0.1 );
  4335.     text.alpha = 1;
  4336.  
  4337.     self waittill( "playerzombie_downed_state_done" );
  4338.  
  4339.     text FadeOverTime( 0.1 );
  4340.     text.alpha = 0;
  4341. }
  4342.  
  4343. playerzombie_infinite_health()
  4344. {
  4345.     self endon( "death" );
  4346.     self endon( "disconnect" );
  4347.  
  4348.     bighealth = 100000;
  4349.  
  4350.     while( 1 )
  4351.     {
  4352.         if( self.health < bighealth )
  4353.         {
  4354.             self.health = bighealth;
  4355.         }
  4356.  
  4357.         wait( 0.1 );
  4358.     }
  4359. }
  4360.  
  4361. playerzombie_soundboard()
  4362. {
  4363.     self endon( "death" );
  4364.     self endon( "disconnect" );
  4365.  
  4366.     self.playerzombie_soundboard_disable = false;
  4367.  
  4368.     self.buttonpressed_use = false;
  4369.     self.buttonpressed_attack = false;
  4370.     self.buttonpressed_ads = false;
  4371.  
  4372.     self.useSound_waitTime = 3 * 1000;  // milliseconds
  4373.     self.useSound_nextTime = GetTime();
  4374.     useSound = "playerzombie_usebutton_sound";
  4375.  
  4376.     self.attackSound_waitTime = 3 * 1000;
  4377.     self.attackSound_nextTime = GetTime();
  4378.     attackSound = "playerzombie_attackbutton_sound";
  4379.  
  4380.     self.adsSound_waitTime = 3 * 1000;
  4381.     self.adsSound_nextTime = GetTime();
  4382.     adsSound = "playerzombie_adsbutton_sound";
  4383.  
  4384.     self.inputSound_nextTime = GetTime();  // don't want to be able to do all sounds at once
  4385.  
  4386.     while( 1 )
  4387.     {
  4388.         if( self.playerzombie_soundboard_disable )
  4389.         {
  4390.             wait( 0.05 );
  4391.             continue;
  4392.         }
  4393.  
  4394.         if( self UseButtonPressed() )
  4395.         {
  4396.             if( self can_do_input( "use" ) )
  4397.             {
  4398.                 self thread playerzombie_play_sound( useSound );
  4399.                 self thread playerzombie_waitfor_buttonrelease( "use" );
  4400.                 self.useSound_nextTime = GetTime() + self.useSound_waitTime;
  4401.             }
  4402.         }
  4403.         else if( self AttackButtonPressed() )
  4404.         {
  4405.             if( self can_do_input( "attack" ) )
  4406.             {
  4407.                 self thread playerzombie_play_sound( attackSound );
  4408.                 self thread playerzombie_waitfor_buttonrelease( "attack" );
  4409.                 self.attackSound_nextTime = GetTime() + self.attackSound_waitTime;
  4410.             }
  4411.         }
  4412.         else if( self AdsButtonPressed() )
  4413.         {
  4414.             if( self can_do_input( "ads" ) )
  4415.             {
  4416.                 self thread playerzombie_play_sound( adsSound );
  4417.                 self thread playerzombie_waitfor_buttonrelease( "ads" );
  4418.                 self.adsSound_nextTime = GetTime() + self.adsSound_waitTime;
  4419.             }
  4420.         }
  4421.  
  4422.         wait( 0.05 );
  4423.     }
  4424. }
  4425.  
  4426. can_do_input( inputType )
  4427. {
  4428.     if( GetTime() < self.inputSound_nextTime )
  4429.     {
  4430.         return false;
  4431.     }
  4432.  
  4433.     canDo = false;
  4434.  
  4435.     switch( inputType )
  4436.     {
  4437.     case "use":
  4438.         if( GetTime() >= self.useSound_nextTime && !self.buttonpressed_use )
  4439.         {
  4440.             canDo = true;
  4441.         }
  4442.         break;
  4443.  
  4444.     case "attack":
  4445.         if( GetTime() >= self.attackSound_nextTime && !self.buttonpressed_attack )
  4446.         {
  4447.             canDo = true;
  4448.         }
  4449.         break;
  4450.  
  4451.     case "ads":
  4452.         if( GetTime() >= self.useSound_nextTime && !self.buttonpressed_ads )
  4453.         {
  4454.             canDo = true;
  4455.         }
  4456.         break;
  4457.  
  4458.     default:
  4459.         ASSERTMSG( "can_do_input(): didn't recognize inputType of " + inputType );
  4460.         break;
  4461.     }
  4462.  
  4463.     return canDo;
  4464. }
  4465.  
  4466. playerzombie_play_sound( alias )
  4467. {
  4468.     self play_sound_on_ent( alias );
  4469. }
  4470.  
  4471. playerzombie_waitfor_buttonrelease( inputType )
  4472. {
  4473.     if( inputType != "use" && inputType != "attack" && inputType != "ads" )
  4474.     {
  4475.         ASSERTMSG( "playerzombie_waitfor_buttonrelease(): inputType of " + inputType + " is not recognized." );
  4476.         return;
  4477.     }
  4478.  
  4479.     notifyString = "waitfor_buttonrelease_" + inputType;
  4480.     self notify( notifyString );
  4481.     self endon( notifyString );
  4482.  
  4483.     if( inputType == "use" )
  4484.     {
  4485.         self.buttonpressed_use = true;
  4486.         while( self UseButtonPressed() )
  4487.         {
  4488.             wait( 0.05 );
  4489.         }
  4490.         self.buttonpressed_use = false;
  4491.     }
  4492.  
  4493.     else if( inputType == "attack" )
  4494.     {
  4495.         self.buttonpressed_attack = true;
  4496.         while( self AttackButtonPressed() )
  4497.         {
  4498.             wait( 0.05 );
  4499.         }
  4500.         self.buttonpressed_attack = false;
  4501.     }
  4502.  
  4503.     else if( inputType == "ads" )
  4504.     {
  4505.         self.buttonpressed_ads = true;
  4506.         while( self AdsButtonPressed() )
  4507.         {
  4508.             wait( 0.05 );
  4509.         }
  4510.         self.buttonpressed_ads = false;
  4511.     }
  4512. }
  4513.  
  4514. remove_ignore_attacker()
  4515. {
  4516.     self notify( "new_ignore_attacker" );
  4517.     self endon( "new_ignore_attacker" );
  4518.     self endon( "disconnect" );
  4519.    
  4520.     if( !isDefined( level.ignore_enemy_timer ) )
  4521.     {
  4522.         level.ignore_enemy_timer = 0.4;
  4523.     }
  4524.    
  4525.     wait( level.ignore_enemy_timer );
  4526.    
  4527.     self.ignoreAttacker = undefined;
  4528. }
  4529.  
  4530. player_damage_override_cheat( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
  4531. {
  4532.     player_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
  4533.     return 0;
  4534. }
  4535.  
  4536.  
  4537. //
  4538. //  player_damage_override
  4539. //      MUST return the value of the damage override
  4540. //
  4541. // MM (08/10/09) - Removed calls to PlayerDamageWrapper because it's always called in
  4542. //      Callback_PlayerDamage now.  We just need to return the damage.
  4543. //
  4544. player_damage_override( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
  4545. {
  4546.     iDamage = self check_player_damage_callbacks( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
  4547.     if ( !iDamage )
  4548.     {
  4549.         return 0;
  4550.     }
  4551.  
  4552.     // WW (8/14/10) - If a player is hit by the crossbow bolt then set them as the holder of the monkey shot
  4553.     if( sWeapon == "crossbow_explosive_upgraded_zm" && sMeansOfDeath == "MOD_IMPACT" )
  4554.     {
  4555.         level.monkey_bolt_holder = self;
  4556.     }
  4557.    
  4558.     // Raven - snigl - Notify of blow gun hit
  4559.     if( GetSubStr(sWeapon, 0, 8 ) == "blow_gun" && sMeansOfDeath == "MOD_IMPACT" )
  4560.     {
  4561.         eAttacker notify( "blow_gun_hit", self, eInflictor );
  4562.     }
  4563.    
  4564.     // WW (8/20/10) - Sledgehammer fix for Issue 43492. This should stop the player from taking any damage while in laststand
  4565.     if( self maps\_laststand::player_is_in_laststand() )
  4566.     {
  4567.         return 0;
  4568.     }
  4569.  
  4570.     if ( isDefined( eInflictor ) )
  4571.     {
  4572.         if ( is_true( eInflictor.water_damage ) )
  4573.         {
  4574.             return 0;
  4575.         }
  4576.     }
  4577.  
  4578.     if( isDefined( eAttacker ) )
  4579.     {
  4580.        
  4581.         //tracking player damage
  4582.         if(is_true(eAttacker.is_zombie))
  4583.         {
  4584.             self.stats["damage_taken"] += iDamage;
  4585.         }
  4586.        
  4587.         if( isDefined( self.ignoreAttacker ) && self.ignoreAttacker == eAttacker )
  4588.         {
  4589.             return 0;
  4590.         }
  4591.        
  4592.         if( (isDefined( eAttacker.is_zombie ) && eAttacker.is_zombie) || level.mutators["mutator_friendlyFire"] )
  4593.         {
  4594.             self.ignoreAttacker = eAttacker;
  4595.             self thread remove_ignore_attacker();
  4596.  
  4597.             if ( isdefined( eAttacker.custom_damage_func ) )
  4598.             {
  4599.                 iDamage = eAttacker [[ eAttacker.custom_damage_func ]]( self );
  4600.             }
  4601.             else if ( isdefined( eAttacker.meleeDamage ) )
  4602.             {
  4603.                 iDamage = eAttacker.meleeDamage;
  4604.             }
  4605.             else
  4606.             {
  4607.                 iDamage = 50;       // 45
  4608.             }
  4609.         }
  4610.        
  4611.         eAttacker notify( "hit_player" );
  4612.        
  4613.        
  4614.         if( is_true(eattacker.is_zombie) && eattacker.animname == "director_zombie" )
  4615.         {
  4616.              self PlaySound( "zmb_director_light_hit" );
  4617.              if(RandomIntRange(0,1) == 0 )
  4618.             {
  4619.                 self thread maps\_zombiemode_audio::create_and_play_dialog( "general", "hitmed" );
  4620.             }
  4621.             else
  4622.             {
  4623.                 self thread maps\_zombiemode_audio::create_and_play_dialog( "general", "hitlrg" );
  4624.             }
  4625.         }
  4626.         else if( sMeansOfDeath != "MOD_FALLING" )
  4627.         {
  4628.             self PlaySound( "evt_player_swiped" );
  4629.             if(RandomIntRange(0,1) == 0 )
  4630.             {
  4631.                 self thread maps\_zombiemode_audio::create_and_play_dialog( "general", "hitmed" );
  4632.             }
  4633.             else
  4634.             {
  4635.                 self thread maps\_zombiemode_audio::create_and_play_dialog( "general", "hitlrg" );
  4636.             }
  4637.         }
  4638.     }
  4639.     finalDamage = iDamage;
  4640.    
  4641.     // claymores and freezegun shatters, like bouncing betties, harm no players
  4642.     if ( is_placeable_mine( sWeapon ) || sWeapon == "freezegun_zm" || sWeapon == "freezegun_upgraded_zm" )
  4643.     {
  4644.         return 0;
  4645.     }
  4646.  
  4647.     if ( isDefined( self.player_damage_override ) )
  4648.     {
  4649.         self thread [[ self.player_damage_override ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
  4650.     }
  4651.  
  4652.     if( sMeansOfDeath == "MOD_FALLING" )
  4653.     {
  4654.         if ( self HasPerk( "specialty_flakjacket" ) && isdefined( self.divetoprone ) && self.divetoprone == 1 )
  4655.         {
  4656.             if ( IsDefined( level.zombiemode_divetonuke_perk_func ) )
  4657.             {
  4658.                 [[ level.zombiemode_divetonuke_perk_func ]]( self, self.origin );
  4659.             }
  4660.  
  4661.             return 0;
  4662.         }
  4663.     }
  4664.  
  4665.     if( sMeansOfDeath == "MOD_PROJECTILE" || sMeansOfDeath == "MOD_PROJECTILE_SPLASH" || sMeansOfDeath == "MOD_GRENADE" || sMeansOfDeath == "MOD_GRENADE_SPLASH" )
  4666.     {
  4667.         // check for reduced damage from flak jacket perk
  4668.         if ( self HasPerk( "specialty_flakjacket" ) )
  4669.         {
  4670.             return 0;
  4671.         }
  4672.  
  4673.         if( self.health > 75 )
  4674.         {
  4675.             // MM (08/10/09)
  4676.             return 75;
  4677.         }
  4678.     }
  4679.  
  4680.     if( iDamage < self.health )
  4681.     {
  4682.         if ( IsDefined( eAttacker ) )
  4683.         {
  4684.             eAttacker.sound_damage_player = self;
  4685.            
  4686.             if( IsDefined( eAttacker.has_legs ) && !eAttacker.has_legs )
  4687.             {
  4688.                 self maps\_zombiemode_audio::create_and_play_dialog( "general", "crawl_hit" );
  4689.             }
  4690.             else if( IsDefined( eAttacker.animname ) && ( eAttacker.animname == "monkey_zombie" ) )
  4691.             {
  4692.                 self maps\_zombiemode_audio::create_and_play_dialog( "general", "monkey_hit" );
  4693.             }
  4694.         }
  4695.        
  4696.         // MM (08/10/09)
  4697.         return finalDamage;
  4698.     }
  4699.     if( level.intermission )
  4700.     {
  4701.         level waittill( "forever" );
  4702.     }
  4703.  
  4704.     players = get_players();
  4705.     count = 0;
  4706.     for( i = 0; i < players.size; i++ )
  4707.     {
  4708.         if( players[i] == self || players[i].is_zombie || players[i] maps\_laststand::player_is_in_laststand() || players[i].sessionstate == "spectator" )
  4709.         {
  4710.             count++;
  4711.         }
  4712.     }
  4713.     if( count < players.size )
  4714.     {
  4715.         // MM (08/10/09)
  4716.         return finalDamage;
  4717.     }
  4718.  
  4719.     //if ( maps\_zombiemode_solo::solo_has_lives() )
  4720.     //{
  4721.     //  SetDvar( "player_lastStandBleedoutTime", "3" );
  4722.     //}
  4723.     //else
  4724.     //{
  4725.     if ( players.size == 1 && flag( "solo_game" ) )
  4726.     {
  4727.         if ( self.lives == 0 )
  4728.         {
  4729.             self.intermission = true;
  4730.         }
  4731.     }
  4732.     //}
  4733.    
  4734.     // WW (01/05/11): When a two players enter a system link game and the client drops the host will be treated as if it was a solo game
  4735.     // when it wasn't. This led to SREs about undefined and int being compared on death (self.lives was never defined on the host). While
  4736.     // adding the check for the solo game flag we found that we would have to create a complex OR inside of the if check below. By breaking
  4737.     // the conditions out in to their own variables we keep the complexity without making it look like a mess.
  4738.     solo_death = ( players.size == 1 && flag( "solo_game" ) && self.lives == 0 ); // there is only one player AND the flag is set AND self.lives equals 0
  4739.     non_solo_death = ( players.size > 1 || ( players.size == 1 && !flag( "solo_game" ) ) ); // the player size is greater than one OR ( players.size equals 1 AND solo flag isn't set )
  4740.  
  4741.     if ( solo_death || non_solo_death ) // if only one player on their last life or any game that started with more than one player
  4742.     {
  4743.         self thread maps\_laststand::PlayerLastStand( eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime );
  4744.         self player_fake_death();
  4745.     }
  4746.  
  4747.     if( count == players.size )
  4748.     {
  4749.         //if ( !maps\_zombiemode_solo::solo_has_lives() )
  4750.         //{
  4751.  
  4752.         if ( players.size == 1 && flag( "solo_game" ) )
  4753.         {
  4754.             if ( self.lives == 0 ) // && !self maps\_laststand::player_is_in_laststand()
  4755.             {
  4756.                
  4757.                 level notify("pre_end_game");
  4758.                 wait_network_frame();
  4759.                
  4760.                 level notify( "end_game" );
  4761.             }
  4762.             else
  4763.             {
  4764.                 self thread wait_and_revive();
  4765.                 return finalDamage;
  4766.             }
  4767.         }
  4768.         else
  4769.         {
  4770.             level notify("pre_end_game");
  4771.             wait_network_frame();
  4772.            
  4773.             level notify( "end_game" );
  4774.         }
  4775.         //}
  4776.  
  4777.         return 0;   // MM (09/16/09) Need to return something
  4778.     }
  4779.     else
  4780.     {
  4781.         // MM (08/10/09)
  4782.         return finalDamage;
  4783.     }
  4784. }
  4785.  
  4786.  
  4787. check_player_damage_callbacks( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime )
  4788. {
  4789.     if ( !isdefined( level.player_damage_callbacks ) )
  4790.     {
  4791.         return iDamage;
  4792.     }
  4793.  
  4794.     for ( i = 0; i < level.player_damage_callbacks.size; i++ )
  4795.     {
  4796.         newDamage = self [[ level.player_damage_callbacks[i] ]]( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, modelIndex, psOffsetTime );
  4797.         if ( -1 != newDamage )
  4798.         {
  4799.             return newDamage;
  4800.         }
  4801.     }
  4802.  
  4803.     return iDamage;
  4804. }
  4805.  
  4806.  
  4807. register_player_damage_callback( func )
  4808. {
  4809.     if ( !isdefined( level.player_damage_callbacks ) )
  4810.     {
  4811.         level.player_damage_callbacks = [];
  4812.     }
  4813.  
  4814.     level.player_damage_callbacks[level.player_damage_callbacks.size] = func;
  4815. }
  4816.  
  4817.  
  4818. wait_and_revive()
  4819. {
  4820.     flag_set( "wait_and_revive" );
  4821.  
  4822.     if ( isdefined( self.waiting_to_revive ) && self.waiting_to_revive == true )
  4823.     {
  4824.         return;
  4825.     }
  4826.  
  4827.     self.waiting_to_revive = true;
  4828.     if ( isdefined( level.exit_level_func ) )
  4829.     {
  4830.         self thread [[ level.exit_level_func ]]();
  4831.     }
  4832.     else
  4833.     {
  4834.         self thread default_exit_level();
  4835.     }
  4836.  
  4837.     // wait to actually go into last stand before reviving
  4838.     while ( 1 )
  4839.     {
  4840.         if ( self maps\_laststand::player_is_in_laststand() )
  4841.         {
  4842.             break;
  4843.         }
  4844.  
  4845.         wait_network_frame();
  4846.     }
  4847.  
  4848.     solo_revive_time = 10.0;
  4849.  
  4850.     self.revive_hud setText( &"ZOMBIE_REVIVING_SOLO", self );
  4851.     self maps\_laststand::revive_hud_show_n_fade( solo_revive_time );
  4852.  
  4853.     flag_wait_or_timeout("instant_revive", solo_revive_time);
  4854.  
  4855.     flag_clear( "wait_and_revive" );
  4856.  
  4857.     self maps\_laststand::auto_revive( self );
  4858.     self.lives--;
  4859.     self.waiting_to_revive = false;
  4860. }
  4861.  
  4862. //
  4863. //      MUST return the value of the damage override
  4864. //
  4865. actor_damage_override( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, modelIndex, psOffsetTime )
  4866. {
  4867.     // WW (8/14/10) - define the owner of the monkey shot
  4868.     if( weapon == "crossbow_explosive_upgraded_zm" && meansofdeath == "MOD_IMPACT" )
  4869.     {
  4870.         level.monkey_bolt_holder = self;
  4871.     }
  4872.    
  4873.     // Raven - snigl - Record what the blow gun hit
  4874.     if( GetSubStr(weapon, 0, 8 ) == "blow_gun" && meansofdeath == "MOD_IMPACT" )
  4875.     {
  4876.         attacker notify( "blow_gun_hit", self, inflictor );
  4877.     }
  4878.  
  4879.     if ( isdefined( attacker.animname ) && attacker.animname == "quad_zombie" )
  4880.     {
  4881.         if ( isdefined( self.animname ) && self.animname == "quad_zombie" )
  4882.         {
  4883.             return 0;
  4884.         }
  4885.     }
  4886.    
  4887.     // skip conditions
  4888.     if( !isdefined( self) || !isdefined( attacker ) )
  4889.         return damage;
  4890.     if ( !isplayer( attacker ) && isdefined( self.non_attacker_func ) )
  4891.     {
  4892.         override_damage = self [[ self.non_attacker_func ]]( damage, weapon );
  4893.         if ( override_damage )
  4894.             return override_damage;
  4895.     }
  4896.     if ( !isplayer( attacker ) && !isplayer( self ) )
  4897.         return damage;
  4898.     if( !isdefined( damage ) || !isdefined( meansofdeath ) )
  4899.         return damage;
  4900.     if( meansofdeath == "" )
  4901.         return damage;
  4902.  
  4903.    
  4904.  
  4905. //  println( "*********HIT :  Zombie health: "+self.health+",  dam:"+damage+", weapon:"+ weapon );
  4906.  
  4907.     old_damage = damage;
  4908.     final_damage = damage;
  4909.  
  4910.     if ( IsDefined( self.actor_damage_func ) )
  4911.     {
  4912.         final_damage = [[ self.actor_damage_func ]]( weapon, old_damage, attacker );
  4913.     }
  4914.  
  4915.     if ( IsDefined( self.actor_full_damage_func ) )
  4916.     {
  4917.         final_damage = [[ self.actor_full_damage_func ]]( inflictor, attacker, damage, flags, meansofdeath, weapon, vpoint, vdir, sHitLoc, modelIndex, psOffsetTime );
  4918.     }
  4919.  
  4920.     // debug
  4921. /#
  4922.         if ( GetDvarInt( #"scr_perkdebug") )
  4923.             println( "Perk/> Damage Factor: " + final_damage/old_damage + " - Pre Damage: " + old_damage + " - Post Damage: " + final_damage );
  4924. #/
  4925.    
  4926.     if( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) )
  4927.         attacker = attacker.owner;
  4928.  
  4929.     if( !isDefined( self.damage_assists ) )
  4930.     {
  4931.         self.damage_assists = [];
  4932.     }
  4933.  
  4934.     if ( !isdefined( self.damage_assists[attacker.entity_num] ) )
  4935.     {
  4936.         self.damage_assists[attacker.entity_num] = attacker;
  4937.     }
  4938.  
  4939.     if( level.mutators[ "mutator_headshotsOnly" ] && !is_headshot( weapon, sHitLoc, meansofdeath ) )
  4940.     {
  4941.         return 0;
  4942.     }
  4943.  
  4944.     if( level.mutators[ "mutator_powerShot" ] )
  4945.     {
  4946.         final_damage = int( final_damage * 1.5 );
  4947.     }
  4948.  
  4949.     if ( is_true( self.in_water ) )
  4950.     {
  4951.         if ( int( final_damage ) >= self.health )
  4952.         {
  4953.             self.water_damage = true;
  4954.         }
  4955.     }
  4956.    
  4957.     // return unchanged damage
  4958.     //iPrintln( final_damage );
  4959.     return int( final_damage );
  4960. }
  4961.  
  4962. is_headshot( sWeapon, sHitLoc, sMeansOfDeath )
  4963. {
  4964.     return (sHitLoc == "head" || sHitLoc == "helmet") && sMeansOfDeath != "MOD_MELEE" && sMeansOfDeath != "MOD_BAYONET" && sMeansOfDeath != "MOD_IMPACT"; //CoD5: MGs need to cause headshots as well. && !isMG( sWeapon );
  4965. }
  4966.  
  4967. actor_killed_override(eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime)
  4968. {
  4969.     if ( game["state"] == "postgame" )
  4970.         return;
  4971.    
  4972.     if( isai(attacker) && isDefined( attacker.script_owner ) )
  4973.     {
  4974.         // if the person who called the dogs in switched teams make sure they don't
  4975.         // get penalized for the kill
  4976.         if ( attacker.script_owner.team != self.aiteam )
  4977.             attacker = attacker.script_owner;
  4978.     }
  4979.        
  4980.     if( attacker.classname == "script_vehicle" && isDefined( attacker.owner ) )
  4981.         attacker = attacker.owner;
  4982.        
  4983.     if( IsPlayer( level.monkey_bolt_holder ) && sMeansOfDeath == "MOD_GRENADE_SPLASH"
  4984.             && ( sWeapon == "crossbow_explosive_upgraded_zm" || sWeapon == "explosive_bolt_upgraded_zm" ) ) //
  4985.     {
  4986.         level._bolt_on_back = level._bolt_on_back + 1;
  4987.     }
  4988.    
  4989.  
  4990.     if ( isdefined( attacker ) && isplayer( attacker ) )
  4991.     {
  4992.         multiplier = 1;
  4993.         if( is_headshot( sWeapon, sHitLoc, sMeansOfDeath ) )
  4994.         {
  4995.             multiplier = 1.5;
  4996.         }
  4997.  
  4998.         type = undefined;
  4999.  
  5000.         //MM (3/18/10) no animname check
  5001.         if ( IsDefined(self.animname) )
  5002.         {
  5003.             switch( self.animname )
  5004.             {
  5005.             case "quad_zombie":
  5006.                 type = "quadkill";
  5007.                 break;
  5008.             case "ape_zombie":
  5009.                 type = "apekill";
  5010.                 break;
  5011.             case "zombie":
  5012.                 type = "zombiekill";
  5013.                 break;
  5014.             case "zombie_dog":
  5015.                 type = "dogkill";
  5016.                 break;
  5017.             }
  5018.         }
  5019.         //if( isDefined( type ) )
  5020.         //{
  5021.         //  value = maps\_zombiemode_rank::getScoreInfoValue( type );
  5022.         //  self process_assist( type, attacker );
  5023.  
  5024.         //  value = int( value * multiplier );
  5025.         //  attacker thread maps\_zombiemode_rank::giveRankXP( type, value, false, false );
  5026.         //}
  5027.     }
  5028.    
  5029.     if(is_true(self.is_ziplining))
  5030.     {
  5031.         self.deathanim = undefined;
  5032.     }
  5033.  
  5034.     if ( IsDefined( self.actor_killed_override ) )
  5035.     {
  5036.         self [[ self.actor_killed_override ]]( eInflictor, attacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, psOffsetTime );
  5037.     }
  5038.  
  5039. }
  5040.  
  5041.  
  5042. process_assist( type, attacker )
  5043. {
  5044.     if ( isDefined( self.damage_assists ) )
  5045.     {
  5046.         for ( j = 0; j < self.damage_assists.size; j++ )
  5047.         {
  5048.             player = self.damage_assists[j];
  5049.            
  5050.             if ( !isDefined( player ) )
  5051.                 continue;
  5052.            
  5053.             if ( player == attacker )
  5054.                 continue;
  5055.            
  5056.             //assist_xp = maps\_zombiemode_rank::getScoreInfoValue( type + "_assist" );
  5057.             //player thread maps\_zombiemode_rank::giveRankXP( type + "_assist", assist_xp );
  5058.         }
  5059.         self.damage_assists = undefined;
  5060.     }
  5061. }
  5062.  
  5063.  
  5064. end_game()
  5065. {
  5066.     level waittill ( "end_game" );
  5067.    
  5068.     clientnotify( "zesn" );
  5069.     level thread maps\_zombiemode_audio::change_zombie_music( "game_over" );
  5070.    
  5071.     //AYERS: Turn off ANY last stand audio at the end of the game
  5072.     players = get_players();
  5073.     for( i = 0; i < players.size; i++ )
  5074.     {
  5075.         setClientSysState( "lsm", "0", players[i] );
  5076.     }
  5077.  
  5078.     StopAllRumbles();
  5079.  
  5080.     level.intermission = true;
  5081.     level.zombie_vars["zombie_powerup_insta_kill_time"] = 0;
  5082.     level.zombie_vars["zombie_powerup_fire_sale_time"] = 0;
  5083.     level.zombie_vars["zombie_powerup_point_doubler_time"] = 0;
  5084.     wait 0.1;
  5085.  
  5086.     update_leaderboards();
  5087.    
  5088.     game_over = [];
  5089.     survived = [];
  5090.    
  5091.     players = get_players();
  5092.     for( i = 0; i < players.size; i++ )
  5093.     {
  5094.         game_over[i] = NewClientHudElem( players[i] );
  5095.         game_over[i].alignX = "center";
  5096.         game_over[i].alignY = "middle";
  5097.         game_over[i].horzAlign = "center";
  5098.         game_over[i].vertAlign = "middle";
  5099.         game_over[i].y -= 130;
  5100.         game_over[i].foreground = true;
  5101.         game_over[i].fontScale = 3;
  5102.         game_over[i].alpha = 0;
  5103.         game_over[i].color = ( 1.0, 1.0, 1.0 );
  5104.         game_over[i] SetText( &"ZOMBIE_GAME_OVER" );
  5105.  
  5106.         game_over[i] FadeOverTime( 1 );
  5107.         game_over[i].alpha = 1;
  5108.         if ( players[i] isSplitScreen() )
  5109.         {
  5110.             game_over[i].y += 40;
  5111.         }
  5112.  
  5113.         survived[i] = NewClientHudElem( players[i] );
  5114.         survived[i].alignX = "center";
  5115.         survived[i].alignY = "middle";
  5116.         survived[i].horzAlign = "center";
  5117.         survived[i].vertAlign = "middle";
  5118.         survived[i].y -= 100;
  5119.         survived[i].foreground = true;
  5120.         survived[i].fontScale = 2;
  5121.         survived[i].alpha = 0;
  5122.         survived[i].color = ( 1.0, 1.0, 1.0 );
  5123.         if ( players[i] isSplitScreen() )
  5124.         {
  5125.             survived[i].y += 40;
  5126.         }
  5127.  
  5128.         //OLD COUNT METHOD
  5129.         if( level.round_number < 2 )
  5130.         {
  5131.             if( level.script == "zombie_moon" )
  5132.             {
  5133.                 if( !isdefined(level.left_nomans_land) )
  5134.                 {
  5135.                     nomanslandtime = level.nml_best_time;
  5136.                     player_survival_time = int( nomanslandtime/1000 );
  5137.                     player_survival_time_in_mins = maps\_zombiemode::to_mins( player_survival_time );      
  5138.                     survived[i] SetText( &"ZOMBIE_SURVIVED_NOMANS", player_survival_time_in_mins );
  5139.                 }
  5140.                 else if( level.left_nomans_land==2 )
  5141.                 {
  5142.                     survived[i] SetText( &"ZOMBIE_SURVIVED_ROUND" );
  5143.                 }
  5144.             }
  5145.             else
  5146.             {
  5147.                 survived[i] SetText( &"ZOMBIE_SURVIVED_ROUND" );
  5148.             }
  5149.         }
  5150.         else
  5151.         {
  5152.             survived[i] SetText( &"ZOMBIE_SURVIVED_ROUNDS", level.round_number );
  5153.         }
  5154.  
  5155.         survived[i] FadeOverTime( 1 );
  5156.         survived[i].alpha = 1;
  5157.     }
  5158.  
  5159.     players = get_players();
  5160.     for (i = 0; i < players.size; i++)
  5161.     {
  5162.         players[i] SetClientDvars( "ammoCounterHide", "1",
  5163.                 "miniscoreboardhide", "1" );
  5164.         //players[i] maps\_zombiemode_solo::solo_destroy_lives_hud();
  5165.         //players[i] maps\_zombiemode_ability::clear_hud();
  5166.     }
  5167.     destroy_chalk_hud();
  5168.  
  5169.     UploadStats();
  5170.  
  5171.     wait( 1 );
  5172.  
  5173.     //play_sound_at_pos( "end_of_game", ( 0, 0, 0 ) );
  5174.     wait( 2 );
  5175.     intermission();
  5176.     wait( level.zombie_vars["zombie_intermission_time"] );
  5177.  
  5178.     level notify( "stop_intermission" );
  5179.     array_thread( get_players(), ::player_exit_level );
  5180.  
  5181.     bbPrint( "zombie_epilogs: rounds %d", level.round_number );
  5182.  
  5183.     players = get_players();
  5184.     for (i = 0; i < players.size; i++)
  5185.     {
  5186.         survived[i] FadeOverTime( 1 );
  5187.         survived[i].alpha = 0;
  5188.         game_over[i] FadeOverTime( 1 );
  5189.         game_over[i].alpha = 0;
  5190.     }
  5191.  
  5192.     wait( 1.5 );
  5193.  
  5194.    
  5195. /*  we are not currently supporting the shared screen tech
  5196.     if( IsSplitScreen() )
  5197.     {
  5198.         players = get_players();
  5199.         for( i = 0; i < players.size; i++ )
  5200.         {
  5201.             share_screen( players[i], false );
  5202.         }
  5203.     }
  5204. */
  5205.  
  5206.     for ( j = 0; j < get_players().size; j++ )
  5207.     {
  5208.         player = get_players()[j];
  5209.         player CameraActivate( false );
  5210.  
  5211.         survived[j] Destroy();
  5212.         game_over[j] Destroy();
  5213.     }
  5214.    
  5215.     if ( level.onlineGame || level.systemLink )
  5216.     {
  5217.         ExitLevel( false );
  5218.     }
  5219.     else
  5220.     {
  5221.         MissionFailed();
  5222.     }
  5223.  
  5224.     // Let's not exit the function
  5225.     wait( 666 );
  5226. }
  5227.  
  5228. update_leaderboards()
  5229. {
  5230.     uploadGlobalStatCounters();
  5231.    
  5232.     if ( GetPlayers().size <= 1 )
  5233.     {
  5234.         //Solo leaderboard!
  5235.         cheater_found = maps\_zombiemode_ffotd::nazizombies_checking_for_cheats();
  5236.         if( cheater_found == false )
  5237.         {
  5238.             //no cheater found - upload score and stats
  5239.             nazizombies_upload_solo_highscore();
  5240.         }
  5241.         return;
  5242.     }
  5243.  
  5244.     if( level.systemLink )
  5245.     {
  5246.         return;
  5247.     }
  5248.  
  5249.     if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
  5250.     {
  5251.         return;
  5252.     }
  5253.  
  5254.     cheater_found = maps\_zombiemode_ffotd::nazizombies_checking_for_cheats();
  5255.     if( cheater_found == false )
  5256.     {
  5257.         //no cheater found - upload score and stats
  5258.         nazizombies_upload_highscore();
  5259.         nazizombies_set_new_zombie_stats();
  5260.     }
  5261. }
  5262.  
  5263. initializeStatTracking()
  5264. {
  5265.     level.global_zombies_killed = 0;
  5266. }
  5267.  
  5268. uploadGlobalStatCounters()
  5269. {
  5270.     incrementCounter( "global_zombies_killed", level.global_zombies_killed );
  5271.     incrementCounter( "global_zombies_killed_by_players", level.zombie_player_killed_count );
  5272.     incrementCounter( "global_zombies_killed_by_traps", level.zombie_trap_killed_count );  
  5273. }
  5274.  
  5275. player_fake_death()
  5276. {
  5277.     level notify ("fake_death");
  5278.     self notify ("fake_death");
  5279.  
  5280.     self TakeAllWeapons();
  5281.     self AllowProne( true );
  5282.     self AllowStand( false );
  5283.     self AllowCrouch( false );
  5284.  
  5285.     self.ignoreme = true;
  5286.     self EnableInvulnerability();
  5287.  
  5288.     wait( 1 );
  5289.     self FreezeControls( true );
  5290. }
  5291.  
  5292. player_exit_level()
  5293. {
  5294.     self AllowStand( true );
  5295.     self AllowCrouch( false );
  5296.     self AllowProne( false );
  5297.  
  5298.     if( IsDefined( self.game_over_bg ) )
  5299.     {
  5300.         self.game_over_bg.foreground = true;
  5301.         self.game_over_bg.sort = 100;
  5302.         self.game_over_bg FadeOverTime( 1 );
  5303.         self.game_over_bg.alpha = 1;
  5304.     }
  5305. }
  5306.  
  5307. player_killed_override()
  5308. {
  5309.     // BLANK
  5310.     level waittill( "forever" );
  5311. }
  5312.  
  5313.  
  5314. injured_walk()
  5315. {
  5316.     self.ground_ref_ent = Spawn( "script_model", ( 0, 0, 0 ) );
  5317.  
  5318.     self.player_speed = 50;
  5319.  
  5320.     // TODO do death countdown 
  5321.     self AllowSprint( false );
  5322.     self AllowProne( false );
  5323.     self AllowCrouch( false );
  5324.     self AllowAds( false );
  5325.     self AllowJump( false );
  5326.  
  5327.     self PlayerSetGroundReferenceEnt( self.ground_ref_ent );
  5328.     self thread limp();
  5329. }
  5330.  
  5331. limp()
  5332. {
  5333.     level endon( "disconnect" );
  5334.     level endon( "death" );
  5335.     // TODO uncomment when/if SetBlur works again
  5336.     //self thread player_random_blur();
  5337.  
  5338.     stumble = 0;
  5339.     alt = 0;
  5340.  
  5341.     while( 1 )
  5342.     {
  5343.         velocity = self GetVelocity();
  5344.         player_speed = abs( velocity[0] ) + abs( velocity[1] );
  5345.  
  5346.         if( player_speed < 10 )
  5347.         {
  5348.             wait( 0.05 );
  5349.             continue;
  5350.         }
  5351.  
  5352.         speed_multiplier = player_speed / self.player_speed;
  5353.  
  5354.         p = RandomFloatRange( 3, 5 );
  5355.         if( RandomInt( 100 ) < 20 )
  5356.         {
  5357.             p *= 3;
  5358.         }
  5359.         r = RandomFloatRange( 3, 7 );
  5360.         y = RandomFloatRange( -8, -2 );
  5361.  
  5362.         stumble_angles = ( p, y, r );
  5363.         stumble_angles = vector_scale( stumble_angles, speed_multiplier );
  5364.  
  5365.         stumble_time = RandomFloatRange( .35, .45 );
  5366.         recover_time = RandomFloatRange( .65, .8 );
  5367.  
  5368.         stumble++;
  5369.         if( speed_multiplier > 1.3 )
  5370.         {
  5371.             stumble++;
  5372.         }
  5373.  
  5374.         self thread stumble( stumble_angles, stumble_time, recover_time );
  5375.  
  5376.         level waittill( "recovered" );
  5377.     }
  5378. }
  5379.  
  5380. stumble( stumble_angles, stumble_time, recover_time, no_notify )
  5381. {
  5382.     stumble_angles = self adjust_angles_to_player( stumble_angles );
  5383.  
  5384.     self.ground_ref_ent RotateTo( stumble_angles, stumble_time, ( stumble_time/4*3 ), ( stumble_time/4 ) );
  5385.     self.ground_ref_ent waittill( "rotatedone" );
  5386.  
  5387.     base_angles = ( RandomFloat( 4 ) - 4, RandomFloat( 5 ), 0 );
  5388.     base_angles = self adjust_angles_to_player( base_angles );
  5389.  
  5390.     self.ground_ref_ent RotateTo( base_angles, recover_time, 0, ( recover_time / 2 ) );
  5391.     self.ground_ref_ent waittill( "rotatedone" );
  5392.  
  5393.     if( !IsDefined( no_notify ) )
  5394.     {
  5395.         level notify( "recovered" );
  5396.     }
  5397. }
  5398.  
  5399. adjust_angles_to_player( stumble_angles )
  5400. {
  5401.     pa = stumble_angles[0];
  5402.     ra = stumble_angles[2];
  5403.  
  5404.     rv = AnglesToRight( self.angles );
  5405.     fv = AnglesToForward( self.angles );
  5406.  
  5407.     rva = ( rv[0], 0, rv[1]*-1 );
  5408.     fva = ( fv[0], 0, fv[1]*-1 );
  5409.     angles = vector_scale( rva, pa );
  5410.     angles = angles + vector_scale( fva, ra );
  5411.     return angles +( 0, stumble_angles[1], 0 );
  5412. }
  5413.  
  5414. coop_player_spawn_placement()
  5415. {
  5416.     structs = getstructarray( "initial_spawn_points", "targetname" );
  5417.  
  5418.     temp_ent = Spawn( "script_model", (0,0,0) );
  5419.     for( i = 0; i < structs.size; i++ )
  5420.     {
  5421.         temp_ent.origin = structs[i].origin;
  5422.         temp_ent placeSpawnpoint();
  5423.         structs[i].origin = temp_ent.origin;
  5424.     }
  5425.     temp_ent Delete();
  5426.  
  5427.     flag_wait( "all_players_connected" );
  5428.  
  5429.     //chrisp - adding support for overriding the default spawning method
  5430.  
  5431.     players = get_players();
  5432.  
  5433.     for( i = 0; i < players.size; i++ )
  5434.     {
  5435.         players[i] setorigin( structs[i].origin );
  5436.         players[i] setplayerangles( structs[i].angles );
  5437.         players[i].spectator_respawn = structs[i];
  5438.     }
  5439. }
  5440.  
  5441.  
  5442. player_zombie_breadcrumb()
  5443. {
  5444.     self endon( "disconnect" );
  5445.     self endon( "spawned_spectator" );
  5446.     level endon( "intermission" );
  5447.  
  5448.     self.zombie_breadcrumbs = [];
  5449.     self.zombie_breadcrumb_distance = 24 * 24; // min dist (squared) the player must move to drop a crumb
  5450.     self.zombie_breadcrumb_area_num = 3;       // the number of "rings" the area breadcrumbs use
  5451.     self.zombie_breadcrumb_area_distance = 16; // the distance between each "ring" of the area breadcrumbs
  5452.  
  5453.     self store_crumb( self.origin );
  5454.     last_crumb = self.origin;
  5455.  
  5456.     self thread debug_breadcrumbs();
  5457.  
  5458.     while( 1 )
  5459.     {
  5460.         wait_time = 0.1;
  5461.        
  5462.     /#
  5463.         if( self isnotarget() )
  5464.         {
  5465.             wait( wait_time );
  5466.             continue;
  5467.         }
  5468.     #/
  5469.    
  5470.         //For cloaking ability
  5471.         //if( self.ignoreme )
  5472.         //{
  5473.         //  wait( wait_time );
  5474.         //  continue;
  5475.         //}
  5476.  
  5477.  
  5478.         store_crumb = true;
  5479.         airborne = false;
  5480.         crumb = self.origin;
  5481.  
  5482. //TODO TEMP SCRIPT for vehicle testing Delete/comment when done
  5483.         if ( !self IsOnGround() && self isinvehicle() )
  5484.         {
  5485.             trace = bullettrace( self.origin + (0,0,10), self.origin, false, undefined );
  5486.             crumb = trace["position"];
  5487.         }
  5488.  
  5489. //TODO TEMP DISABLE for vehicle testing.  Uncomment when reverting
  5490. //      if ( !self IsOnGround() )
  5491. //      {
  5492. //          airborne = true;
  5493. //          store_crumb = false;
  5494. //          wait_time = 0.05;
  5495. //      }
  5496. //     
  5497.         if( !airborne && DistanceSquared( crumb, last_crumb ) < self.zombie_breadcrumb_distance )
  5498.         {
  5499.             store_crumb = false;
  5500.         }
  5501.  
  5502.         if ( airborne && self IsOnGround() )
  5503.         {
  5504.             // player was airborne, store crumb now that he's on the ground
  5505.             store_crumb = true;
  5506.             airborne = false;
  5507.         }
  5508.        
  5509.         if( isDefined( level.custom_breadcrumb_store_func ) )
  5510.         {
  5511.             store_crumb = self [[ level.custom_breadcrumb_store_func ]]( store_crumb );
  5512.         }
  5513.        
  5514.         if( isDefined( level.custom_airborne_func ) )
  5515.         {
  5516.             airborne = self [[ level.custom_airborne_func ]]( airborne );
  5517.         }
  5518.        
  5519.         if( store_crumb )
  5520.         {
  5521.             debug_print( "Player is storing breadcrumb " + crumb );
  5522.            
  5523.             if( IsDefined(self.node) )
  5524.             {
  5525.                 debug_print( "has closest node " );
  5526.             }
  5527.            
  5528.             last_crumb = crumb;
  5529.             self store_crumb( crumb );
  5530.         }
  5531.  
  5532.         wait( wait_time );
  5533.     }
  5534. }
  5535.  
  5536.  
  5537. store_crumb( origin )
  5538. {
  5539.     offsets = [];
  5540.     height_offset = 32;
  5541.    
  5542.     index = 0;
  5543.     for( j = 1; j <= self.zombie_breadcrumb_area_num; j++ )
  5544.     {
  5545.         offset = ( j * self.zombie_breadcrumb_area_distance );
  5546.        
  5547.         offsets[0] = ( origin[0] - offset, origin[1], origin[2] );
  5548.         offsets[1] = ( origin[0] + offset, origin[1], origin[2] );
  5549.         offsets[2] = ( origin[0], origin[1] - offset, origin[2] );
  5550.         offsets[3] = ( origin[0], origin[1] + offset, origin[2] );
  5551.  
  5552.         offsets[4] = ( origin[0] - offset, origin[1], origin[2] + height_offset );
  5553.         offsets[5] = ( origin[0] + offset, origin[1], origin[2] + height_offset );
  5554.         offsets[6] = ( origin[0], origin[1] - offset, origin[2] + height_offset );
  5555.         offsets[7] = ( origin[0], origin[1] + offset, origin[2] + height_offset );
  5556.  
  5557.         for ( i = 0; i < offsets.size; i++ )
  5558.         {
  5559.             self.zombie_breadcrumbs[index] = offsets[i];
  5560.             index++;
  5561.         }
  5562.     }
  5563. }
  5564.  
  5565.  
  5566. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5567. /////////////////////////////////////////////////LEADERBOARD CODE///////////////////////////////////////////////////////////
  5568. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5569. to_mins( seconds )
  5570. {
  5571.     hours = 0;
  5572.     minutes = 0;
  5573.    
  5574.     if( seconds > 59 )
  5575.     {
  5576.         minutes = int( seconds / 60 );
  5577.  
  5578.         seconds = int( seconds * 1000 ) % ( 60 * 1000 );
  5579.         seconds = seconds * 0.001;
  5580.  
  5581.         if( minutes > 59 )
  5582.         {
  5583.             hours = int( minutes / 60 );
  5584.             minutes = int( minutes * 1000 ) % ( 60 * 1000 );
  5585.             minutes = minutes * 0.001;     
  5586.         }
  5587.     }
  5588.  
  5589.     if( hours < 10 )
  5590.     {
  5591.         hours = "0" + hours;
  5592.     }
  5593.  
  5594.     if( minutes < 10 )
  5595.     {
  5596.         minutes = "0" + minutes;
  5597.     }
  5598.  
  5599.     seconds = Int( seconds );
  5600.     if( seconds < 10 )
  5601.     {
  5602.         seconds = "0" + seconds;
  5603.     }
  5604.  
  5605.     combined = "" + hours  + ":" + minutes  + ":" + seconds;
  5606.  
  5607.     return combined;
  5608. }
  5609.  
  5610. //This is used to upload the score to the solo leaderboard for the moon map(No Man's Land)
  5611. nazizombies_upload_solo_highscore()
  5612. {
  5613.     map_name = GetDvar( #"mapname" );
  5614.  
  5615.     if ( !isZombieLeaderboardAvailable( map_name, "kills" ) )
  5616.         return;
  5617.  
  5618.     players = get_players();       
  5619.     for( i = 0; i < players.size; i++ )
  5620.     {
  5621.         if( map_name == "zombie_moon" )
  5622.         {
  5623.             nomanslandtime = level.nml_best_time;
  5624.             nomansland_kills = level.nml_kills;
  5625.             nomansland_score = level.nml_score;
  5626.             player_survival_time = int( nomanslandtime/1000 );
  5627.             total_score = nomansland_score; //players[i].score_total;
  5628.             total_kills = nomansland_kills; //players[i].kills;
  5629.            
  5630.             leaderboard_number = getZombieLeaderboardNumber( map_name, "kills" );
  5631.            
  5632.             rounds_survived = level.round_number;
  5633.            
  5634.             if( isdefined(level.nml_didteleport) && (level.nml_didteleport==false) )
  5635.             {
  5636.                 rounds_survived = 0;
  5637.             }
  5638.            
  5639. /#             
  5640.             if( GetDvarInt( #"zombie_cheat" ) >= 1 )
  5641.             {
  5642.                 level.devcheater = 1;
  5643.             }
  5644.            
  5645.             if( isdefined(level.devcheater) && level.devcheater )
  5646.             {
  5647.                 rounds_survived = -1;
  5648.             }
  5649. #/         
  5650.  
  5651.             rankNumber = makeNMLRankNumberSolo( total_kills, total_score );
  5652.             if( !isdefined(level.round_number) )
  5653.             {
  5654.                 level.round_number = 0;
  5655.             }
  5656.            
  5657.             if( !isdefined(level.nml_pap) )
  5658.             {
  5659.                 level.nml_pap = 0;
  5660.             }
  5661.             if( !isdefined(level.nml_speed) )
  5662.             {
  5663.                 level.nml_speed = 0;
  5664.             }
  5665.             if( !isdefined(level.nml_jugg) )
  5666.             {
  5667.                 level.nml_jugg = 0;
  5668.             }
  5669.            
  5670.  
  5671.             if( !isdefined(level.sololb_build_number) )
  5672.             {
  5673.                 level.sololb_build_number = 48;
  5674.             }
  5675.  
  5676.             players[i] UploadScore( leaderboard_number, int(rankNumber), total_kills, total_score, player_survival_time, rounds_survived, level.sololb_build_number, level.nml_pap, level.nml_speed, level.nml_jugg );
  5677.         }
  5678.     }
  5679. }
  5680.  
  5681. makeNMLRankNumberSolo( total_kills, total_score )
  5682. {
  5683.     maximum_survival_time = 108000;
  5684.  
  5685.     // Upper cap on total_kills is 2000
  5686.     if( total_kills > 2000 )
  5687.         total_kills = 2000;
  5688.    
  5689.     // Upper cap on player total score
  5690.     if( total_score > 99999 )
  5691.         total_score = 99999;
  5692.  
  5693.    
  5694.     //pad out ranking time.
  5695.     score_padding = "";
  5696.     if ( total_score < 10 )
  5697.         score_padding += "0000";
  5698.     else if( total_score < 100 )
  5699.         score_padding += "000";
  5700.     else if( total_score < 1000 )
  5701.         score_padding += "00";
  5702.     else if( total_score < 10000 )
  5703.         score_padding += "0";
  5704.  
  5705.     // Trying to make the rankNumber by combining kills with 5 digit padded points earned.
  5706.     rankNumber = total_kills + score_padding + total_score;
  5707.  
  5708.     return rankNumber;
  5709. }
  5710.  
  5711. //CODER MOD: TOMMY K
  5712. nazizombies_upload_highscore()
  5713. {
  5714.     // Nazi Zombie Leaderboards
  5715.     // nazi_zombie_prototype_waves = 13
  5716.     // nazi_zombie_prototype_points = 14
  5717.  
  5718.     // this has gotta be the dumbest way of doing this, but at 1:33am in the morning my brain is fried!
  5719.     playersRank = 1;
  5720.     if( level.players_playing == 1 )
  5721.         playersRank = 4;
  5722.     else if( level.players_playing == 2 )
  5723.         playersRank = 3;
  5724.     else if( level.players_playing == 3 )
  5725.         playersRank = 2;
  5726.  
  5727.     map_name = GetDvar( #"mapname" );
  5728.  
  5729.     if ( !isZombieLeaderboardAvailable( map_name, "waves" ) || !isZombieLeaderboardAvailable( map_name, "points" ) )
  5730.         return;
  5731.  
  5732.     players = get_players();       
  5733.     for( i = 0; i < players.size; i++ )
  5734.     {
  5735.         pre_highest_wave = players[i] playerZombieStatGet( map_name, "highestwave" );
  5736.         pre_time_in_wave = players[i] playerZombieStatGet( map_name, "timeinwave" );
  5737.  
  5738.         new_highest_wave = level.round_number + "" + playersRank;
  5739.         new_highest_wave = int( new_highest_wave );
  5740.  
  5741.         if( new_highest_wave >= pre_highest_wave )
  5742.         {
  5743.             if( players[i].zombification_time == 0 )
  5744.             {
  5745.                 players[i].zombification_time = GetTime();
  5746.             }
  5747.  
  5748.             player_survival_time = players[i].zombification_time - level.round_start_time;
  5749.             player_survival_time = int( player_survival_time/1000 );    
  5750.            
  5751.             /*
  5752.             if( map_name == "zombie_moon" )
  5753.             {
  5754.                 nomanslandtime = level.nml_best_time ;
  5755.                 player_survival_time = int( nomanslandtime/1000 );
  5756.                 //player_survival_time_in_mins = maps\_zombiemode::to_mins( player_survival_time );
  5757.                 //IPrintLnBold( "NO MANS LAND = " + player_survival_time_in_mins );
  5758.             }  
  5759.             */ 
  5760.  
  5761.             if( new_highest_wave > pre_highest_wave || player_survival_time > pre_time_in_wave )
  5762.             {
  5763.                 rankNumber = makeRankNumber( level.round_number, playersRank, player_survival_time );
  5764.  
  5765.                 leaderboard_number = getZombieLeaderboardNumber( map_name, "waves" );
  5766.  
  5767.                 players[i] UploadScore( leaderboard_number, int(rankNumber), level.round_number, player_survival_time, level.players_playing );
  5768.                 //players[i] UploadScore( leaderboard_number, int(rankNumber), level.round_number );
  5769.  
  5770.                 players[i] playerZombieStatSet( map_name, "highestwave", new_highest_wave );
  5771.                 players[i] playerZombieStatSet( map_name, "timeinwave", player_survival_time );
  5772.             }
  5773.         }
  5774.  
  5775.         pre_total_points = players[i] playerZombieStatGet( map_name, "totalpoints" );
  5776.         if( players[i].score_total > pre_total_points )
  5777.         {
  5778.             leaderboard_number = getZombieLeaderboardNumber( map_name, "points" );
  5779.  
  5780.             players[i] UploadScore( leaderboard_number, players[i].score_total, players[i].kills, level.players_playing );
  5781.  
  5782.             players[i] playerZombieStatSet( map_name, "totalpoints", players[i].score_total ); 
  5783.         }
  5784.     }
  5785. }
  5786.  
  5787. isZombieLeaderboardAvailable( map, type )
  5788. {
  5789.     if ( !isDefined( level.zombieLeaderboardNumber[map] ) )
  5790.         return 0;
  5791.    
  5792.     if ( !isDefined( level.zombieLeaderboardNumber[map][type] ) )
  5793.         return 0;
  5794.  
  5795.     return 1;
  5796. }
  5797.  
  5798. getZombieLeaderboardNumber( map, type )
  5799. {
  5800.     if ( !isDefined( level.zombieLeaderboardNumber[map][type] ) )
  5801.         assertMsg( "Unknown leaderboard number for map " + map + "and type " + type );
  5802.    
  5803.     return level.zombieLeaderboardNumber[map][type];
  5804. }
  5805.  
  5806. getZombieStatVariable( map, variable )
  5807. {
  5808.     if ( !isDefined( level.zombieLeaderboardStatVariable[map][variable] ) )
  5809.         assertMsg( "Unknown stat variable " + variable + " for map " + map );
  5810.        
  5811.     return level.zombieLeaderboardStatVariable[map][variable];
  5812. }
  5813.  
  5814. playerZombieStatGet( map, variable )
  5815. {
  5816.     stat_variable = getZombieStatVariable( map, variable );
  5817.     result = self zombieStatGet( stat_variable );
  5818.  
  5819.     return result;
  5820. }
  5821.  
  5822. playerZombieStatSet( map, variable, value )
  5823. {
  5824.     stat_variable = getZombieStatVariable( map, variable );
  5825.     self zombieStatSet( stat_variable, value );
  5826. }
  5827.  
  5828. nazizombies_set_new_zombie_stats()
  5829. {
  5830.     players = get_players();       
  5831.     for( i = 0; i < players.size; i++ )
  5832.     {
  5833.         //grab stat and add final totals
  5834.         total_kills = players[i] zombieStatGet( "zombie_kills" ) + players[i].stats["kills"];
  5835.         total_points = players[i] zombieStatGet( "zombie_points" ) + players[i].stats["score"];
  5836.         total_rounds = players[i] zombieStatGet( "zombie_rounds" ) + (level.round_number - 1); // rounds survived
  5837.         total_downs = players[i] zombieStatGet( "zombie_downs" ) + players[i].stats["downs"];
  5838.         total_revives = players[i] zombieStatGet( "zombie_revives" ) + players[i].stats["revives"];
  5839.         total_perks = players[i] zombieStatGet( "zombie_perks_consumed" ) + players[i].stats["perks"];
  5840.         total_headshots = players[i] zombieStatGet( "zombie_heashots" ) + players[i].stats["headshots"];
  5841.         total_zombie_gibs = players[i] zombieStatGet( "zombie_gibs" ) + players[i].stats["zombie_gibs"];
  5842.  
  5843.         //set zombie stats
  5844.         players[i] zombieStatSet( "zombie_kills", total_kills );
  5845.         players[i] zombieStatSet( "zombie_points", total_points );
  5846.         players[i] zombieStatSet( "zombie_rounds", total_rounds );
  5847.         players[i] zombieStatSet( "zombie_downs", total_downs );
  5848.         players[i] zombieStatSet( "zombie_revives", total_revives );
  5849.         players[i] zombieStatSet( "zombie_perks_consumed", total_perks );
  5850.         players[i] zombieStatSet( "zombie_heashots", total_headshots );
  5851.         players[i] zombieStatSet( "zombie_gibs", total_zombie_gibs );
  5852.     }
  5853. }
  5854.  
  5855. makeRankNumber( wave, players, time )
  5856. {
  5857.     if( time > 86400 )
  5858.         time = 86400; // cap it at like 1 day, need to cap cause you know some muppet is gonna end up trying it
  5859.  
  5860.     //pad out time
  5861.     padding = "";
  5862.     if ( 10 > time )
  5863.         padding += "0000";
  5864.     else if( 100 > time )
  5865.         padding += "000";
  5866.     else if( 1000 > time )
  5867.         padding += "00";
  5868.     else if( 10000 > time )
  5869.         padding += "0";
  5870.  
  5871.     rank = wave + "" + players + padding + time;
  5872.  
  5873.     return rank;
  5874. }
  5875.  
  5876.  
  5877. //CODER MOD: TOMMY K
  5878. /*
  5879. =============
  5880. zombieStatGet
  5881.  
  5882. Returns the value of the named stat
  5883. =============
  5884. */
  5885. zombieStatGet( dataName )
  5886. {
  5887.     if( level.systemLink )
  5888.     {
  5889.         return;
  5890.     }
  5891.     if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
  5892.     {
  5893.         return;
  5894.     }
  5895.  
  5896.     return ( self getdstat( "PlayerStatsList", dataName ) );
  5897. }
  5898.  
  5899. //CODER MOD: TOMMY K
  5900. /*
  5901. =============
  5902. zombieStatSet
  5903.  
  5904. Sets the value of the named stat
  5905. =============
  5906. */
  5907. zombieStatSet( dataName, value )
  5908. {
  5909.     if( level.systemLink )
  5910.     {
  5911.         return;
  5912.     }
  5913.     if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
  5914.     {
  5915.         return;
  5916.     }
  5917.  
  5918.     self setdstat( "PlayerStatsList", dataName, value );
  5919. }
  5920.  
  5921.  
  5922. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5923. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5924. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  5925.  
  5926. //
  5927. // INTERMISSION =========================================================== //
  5928. //
  5929.  
  5930. intermission()
  5931. {
  5932.     level.intermission = true;
  5933.     level notify( "intermission" );
  5934.  
  5935.     players = get_players();
  5936.     for( i = 0; i < players.size; i++ )
  5937.     {
  5938.         setclientsysstate( "levelNotify", "zi", players[i] ); // Tell clientscripts we're in zombie intermission
  5939.  
  5940.         players[i] SetClientDvars( "cg_thirdPerson", "0",
  5941.             "cg_fov", "65" );
  5942.  
  5943.         players[i].health = 100; // This is needed so the player view doesn't get stuck
  5944.         players[i] thread [[level.custom_intermission]]();
  5945.     }
  5946.  
  5947.     wait( 0.25 );
  5948.  
  5949.     // Delay the last stand monitor so we are 100% sure the zombie intermission ("zi") is set on the cients
  5950.     players = get_players();
  5951.     for( i = 0; i < players.size; i++ )
  5952.     {
  5953.         setClientSysState( "lsm", "0", players[i] );
  5954.     }
  5955.  
  5956.     visionset = "zombie";
  5957.     if( IsDefined( level.zombie_vars["intermission_visionset"] ) )
  5958.     {
  5959.         visionset = level.zombie_vars["intermission_visionset"];
  5960.     }
  5961.  
  5962.     level thread maps\_utility::set_all_players_visionset( visionset, 2 );
  5963.     level thread zombie_game_over_death();
  5964. }
  5965.  
  5966. zombie_game_over_death()
  5967. {
  5968.     // Kill remaining zombies, in style!
  5969.     zombies = GetAiArray( "axis" );
  5970.     for( i = 0; i < zombies.size; i++ )
  5971.     {
  5972.         if( !IsAlive( zombies[i] ) )
  5973.         {
  5974.             continue;
  5975.         }
  5976.  
  5977.         zombies[i] SetGoalPos( zombies[i].origin );
  5978.     }
  5979.  
  5980.     for( i = 0; i < zombies.size; i++ )
  5981.     {
  5982.         if( !IsAlive( zombies[i] ) )
  5983.         {
  5984.             continue;
  5985.         }
  5986.  
  5987.         wait( 0.5 + RandomFloat( 2 ) );
  5988.  
  5989.         if ( isdefined( zombies[i] ) )
  5990.         {
  5991.             zombies[i] maps\_zombiemode_spawner::zombie_head_gib();
  5992.             zombies[i] DoDamage( zombies[i].health + 666, zombies[i].origin );
  5993.         }
  5994.     }
  5995. }
  5996.  
  5997. player_intermission()
  5998. {
  5999.     self closeMenu();
  6000.     self closeInGameMenu();
  6001.  
  6002.     level endon( "stop_intermission" );
  6003.     self endon("disconnect");
  6004.     self endon("death");
  6005.     self notify( "_zombie_game_over" ); // ww: notify so hud elements know when to leave
  6006.  
  6007.     //Show total gained point for end scoreboard and lobby
  6008.     self.score = self.score_total;
  6009.  
  6010.     self.sessionstate = "intermission";
  6011.     self.spectatorclient = -1;
  6012.     self.killcamentity = -1;
  6013.     self.archivetime = 0;
  6014.     self.psoffsettime = 0;
  6015.     self.friendlydamage = undefined;
  6016.  
  6017.     points = getstructarray( "intermission", "targetname" );
  6018.  
  6019.     if( !IsDefined( points ) || points.size == 0 )
  6020.     {
  6021.         points = getentarray( "info_intermission", "classname" );
  6022.         if( points.size < 1 )
  6023.         {
  6024.             println( "NO info_intermission POINTS IN MAP" );
  6025.             return;
  6026.         }  
  6027.     }
  6028.  
  6029.     self.game_over_bg = NewClientHudelem( self );
  6030.     self.game_over_bg.horzAlign = "fullscreen";
  6031.     self.game_over_bg.vertAlign = "fullscreen";
  6032.     self.game_over_bg SetShader( "black", 640, 480 );
  6033.     self.game_over_bg.alpha = 1;
  6034.  
  6035.     org = undefined;
  6036.     while( 1 )
  6037.     {
  6038.         points = array_randomize( points );
  6039.         for( i = 0; i < points.size; i++ )
  6040.         {
  6041.             point = points[i];
  6042.             // Only spawn once if we are using 'moving' org
  6043.             // If only using info_intermissions, this will respawn after 5 seconds.
  6044.             if( !IsDefined( org ) )
  6045.             {
  6046.                 self Spawn( point.origin, point.angles );
  6047.             }
  6048.  
  6049.             // Only used with STRUCTS
  6050.             if( IsDefined( points[i].target ) )
  6051.             {
  6052.                 if( !IsDefined( org ) )
  6053.                 {
  6054.                     org = Spawn( "script_model", self.origin + ( 0, 0, -60 ) );
  6055.                     org SetModel("tag_origin");
  6056.                 }
  6057.  
  6058. //              self LinkTo( org, "", ( 0, 0, -60 ), ( 0, 0, 0 ) );
  6059. //              self SetPlayerAngles( points[i].angles );
  6060.                 org.origin = points[i].origin;
  6061.                 org.angles = points[i].angles;
  6062.                
  6063.  
  6064.                 for ( j = 0; j < get_players().size; j++ )
  6065.                 {
  6066.                     player = get_players()[j];
  6067.                     player CameraSetPosition( org );
  6068.                     player CameraSetLookAt();
  6069.                     player CameraActivate( true ); 
  6070.                 }
  6071.  
  6072.                 speed = 20;
  6073.                 if( IsDefined( points[i].speed ) )
  6074.                 {
  6075.                     speed = points[i].speed;
  6076.                 }
  6077.  
  6078.                 target_point = getstruct( points[i].target, "targetname" );
  6079.                 dist = Distance( points[i].origin, target_point.origin );
  6080.                 time = dist / speed;
  6081.  
  6082.                 q_time = time * 0.25;
  6083.                 if( q_time > 1 )
  6084.                 {
  6085.                     q_time = 1;
  6086.                 }
  6087.  
  6088.                 self.game_over_bg FadeOverTime( q_time );
  6089.                 self.game_over_bg.alpha = 0;
  6090.  
  6091.                 org MoveTo( target_point.origin, time, q_time, q_time );
  6092.                 org RotateTo( target_point.angles, time, q_time, q_time );
  6093.                 wait( time - q_time );
  6094.  
  6095.                 self.game_over_bg FadeOverTime( q_time );
  6096.                 self.game_over_bg.alpha = 1;
  6097.  
  6098.                 wait( q_time );
  6099.             }
  6100.             else
  6101.             {
  6102.                 self.game_over_bg FadeOverTime( 1 );
  6103.                 self.game_over_bg.alpha = 0;
  6104.  
  6105.                 wait( 5 );
  6106.                
  6107.                 self.game_over_bg thread fade_up_over_time(1);
  6108.  
  6109.                 //wait( 1 );
  6110.             }
  6111.         }
  6112.     }
  6113. }
  6114.  
  6115. fade_up_over_time(t)
  6116. {
  6117.         self FadeOverTime( t );
  6118.         self.alpha = 1;
  6119. }
  6120.  
  6121. prevent_near_origin()
  6122. {
  6123.     while (1)
  6124.     {
  6125.         players = get_players();
  6126.  
  6127.         for (i = 0; i < players.size; i++)
  6128.         {
  6129.             for (q = 0; q < players.size; q++)
  6130.             {
  6131.                 if (players[i] != players[q])
  6132.                 {  
  6133.                     if (check_to_kill_near_origin(players[i], players[q]))
  6134.                     {
  6135.                         p1_org = players[i].origin;
  6136.                         p2_org = players[q].origin;
  6137.  
  6138.                         wait 5;
  6139.  
  6140.                         if (check_to_kill_near_origin(players[i], players[q]))
  6141.                         {
  6142.                             if ( (distance(players[i].origin, p1_org) < 30) && distance(players[q].origin, p2_org) < 30)
  6143.                             {
  6144.                                 setsaveddvar("player_deathInvulnerableTime", 0);
  6145.                                 players[i] DoDamage( players[i].health + 1000, players[i].origin, undefined, undefined, "riflebullet" );
  6146.                                 setsaveddvar("player_deathInvulnerableTime", level.startInvulnerableTime); 
  6147.                             }
  6148.                         }
  6149.                     }  
  6150.                 }
  6151.             }  
  6152.         }
  6153.  
  6154.         wait 0.2;
  6155.     }
  6156. }
  6157.  
  6158. check_to_kill_near_origin(player1, player2)
  6159. {
  6160.     if (!isdefined(player1) || !isdefined(player2))
  6161.     {
  6162.         return false;      
  6163.     }
  6164.  
  6165.     if (distance(player1.origin, player2.origin) > 12)
  6166.     {
  6167.         return false;
  6168.     }
  6169.  
  6170.     if ( player1 maps\_laststand::player_is_in_laststand() || player2 maps\_laststand::player_is_in_laststand() )
  6171.     {
  6172.         return false;
  6173.     }
  6174.  
  6175.     if (!isalive(player1) || !isalive(player2))
  6176.     {
  6177.         return false;      
  6178.     }
  6179.  
  6180.     return true;
  6181. }
  6182.  
  6183.  
  6184. //
  6185. crawler_round_tracker()
  6186. {  
  6187.     level.crawler_round_count = 1;
  6188.  
  6189.     level.next_crawler_round = 4;
  6190.  
  6191.     sav_func = level.round_spawn_func;
  6192.     while ( 1 )
  6193.     {
  6194.         level waittill ( "between_round_over" );
  6195.  
  6196. /#
  6197.             if( GetDvarInt( #"force_crawlers" ) > 0 )
  6198.             {
  6199.                 next_crawler_round = level.round_number;
  6200.             }
  6201. #/
  6202.  
  6203.             if ( level.round_number == level.next_crawler_round )
  6204.             {
  6205.                 sav_func = level.round_spawn_func;
  6206.                 crawler_round_start();
  6207.                 level.round_spawn_func = ::round_spawning;
  6208.  
  6209.                 if ( IsDefined( level.next_dog_round ) )
  6210.                 {
  6211.                     level.next_crawler_round = level.next_dog_round + randomintrange( 2, 3 );
  6212.                 }
  6213.                 else
  6214.                 {
  6215.                     level.next_crawler_round = randomintrange( 4, 6 );
  6216.                 }
  6217. /#
  6218.                 get_players()[0] iprintln( "Next crawler round: " + level.next_crawler_round );
  6219. #/
  6220.             }
  6221.             else if ( flag( "crawler_round" ) )
  6222.             {
  6223.                 crawler_round_stop();
  6224.  
  6225.                 // Don't trample over the round_spawn_func setting
  6226.                 if ( IsDefined( level.next_dog_round ) &&
  6227.                      level.next_dog_round == level.round_number )
  6228.                 {
  6229.                     level.round_spawn_func = sav_func;
  6230.                 }
  6231.  
  6232.                 level.crawler_round_count += 1;
  6233.             }          
  6234.     }  
  6235. }
  6236.  
  6237.  
  6238. crawler_round_start()
  6239. {
  6240.     flag_set( "crawler_round" );
  6241.     if(!IsDefined (level.crawlerround_nomusic))
  6242.     {
  6243.         level.crawlerround_nomusic = 0;
  6244.     }
  6245.     level.crawlerround_nomusic = 1;
  6246.     level notify( "crawler_round_starting" );
  6247.     clientnotify( "crawler_start" );
  6248. }
  6249.  
  6250.  
  6251. crawler_round_stop()
  6252. {
  6253.     flag_clear( "crawler_round" );
  6254.  
  6255.     if(!IsDefined (level.crawlerround_nomusic))
  6256.     {
  6257.         level.crawlerround_nomusic = 0;
  6258.     }
  6259.     level.crawlerround_nomusic = 0;
  6260.     level notify( "crawler_round_ending" );
  6261.     clientnotify( "crawler_stop" );
  6262. }
  6263.  
  6264. default_exit_level()
  6265. {
  6266.     zombies = GetAiArray( "axis" );
  6267.     for ( i = 0; i < zombies.size; i++ )
  6268.     {
  6269.         if ( is_true( zombies[i].ignore_solo_last_stand ) )
  6270.         {
  6271.             continue;
  6272.         }
  6273.  
  6274.         if ( isDefined( zombies[i].find_exit_point ) )
  6275.         {
  6276.             zombies[i] thread [[ zombies[i].find_exit_point ]]();
  6277.             continue;
  6278.         }
  6279.  
  6280.         if ( zombies[i].ignoreme )
  6281.         {
  6282.             zombies[i] thread default_delayed_exit();
  6283.         }
  6284.         else
  6285.         {
  6286.             zombies[i] thread default_find_exit_point();
  6287.         }
  6288.     }
  6289. }
  6290.  
  6291. default_delayed_exit()
  6292. {
  6293.     self endon( "death" );
  6294.  
  6295.     while ( 1 )
  6296.     {
  6297.         if ( !flag( "wait_and_revive" ) )
  6298.         {
  6299.             return;
  6300.         }
  6301.  
  6302.         // broke through the barricade, find an exit point
  6303.         if ( !self.ignoreme )
  6304.         {
  6305.             break;
  6306.         }
  6307.         wait_network_frame();
  6308.     }
  6309.  
  6310.     self thread default_find_exit_point();
  6311. }
  6312.  
  6313. default_find_exit_point()
  6314. {
  6315.     self endon( "death" );
  6316.  
  6317.     player = getplayers()[0];
  6318.  
  6319.     dist_zombie = 0;
  6320.     dist_player = 0;
  6321.     dest = 0;
  6322.  
  6323.     away = VectorNormalize( self.origin - player.origin );
  6324.     endPos = self.origin + vector_scale( away, 600 );
  6325.  
  6326.     locs = array_randomize( level.enemy_dog_locations );
  6327.  
  6328.     for ( i = 0; i < locs.size; i++ )
  6329.     {
  6330.         dist_zombie = DistanceSquared( locs[i].origin, endPos );
  6331.         dist_player = DistanceSquared( locs[i].origin, player.origin );
  6332.  
  6333.         if ( dist_zombie < dist_player )
  6334.         {
  6335.             dest = i;
  6336.             break;
  6337.         }
  6338.     }
  6339.  
  6340.     self notify( "stop_find_flesh" );
  6341.     self notify( "zombie_acquire_enemy" );
  6342.  
  6343.     self setgoalpos( locs[dest].origin );
  6344.  
  6345.     while ( 1 )
  6346.     {
  6347.         if ( !flag( "wait_and_revive" ) )
  6348.         {
  6349.             break;
  6350.         }
  6351.         wait_network_frame();
  6352.     }
  6353.    
  6354.     self thread maps\_zombiemode_spawner::find_flesh();
  6355. }
  6356.  
  6357. play_level_start_vox_delayed()
  6358. {
  6359.     wait(5);
  6360.     players = getplayers();
  6361.     num = RandomIntRange( 0, players.size );
  6362.     players[num] maps\_zombiemode_audio::create_and_play_dialog( "general", "intro" );
  6363. }
  6364.  
  6365.  
  6366. //show some stats on the screen ( debug only )
  6367. init_screen_stats()
  6368. {
  6369.        
  6370.     level.zombies_timeout_spawn_info = NewHudElem();
  6371.     level.zombies_timeout_spawn_info.alignX = "right";
  6372.     level.zombies_timeout_spawn_info.x = 100;
  6373.     level.zombies_timeout_spawn_info.y = 80;
  6374.     level.zombies_timeout_spawn_info.label = "Timeout(Spawncloset): ";
  6375.     level.zombies_timeout_spawn_info.fontscale = 1.2;
  6376.    
  6377.  
  6378.     level.zombies_timeout_playspace_info = NewHudElem();
  6379.     level.zombies_timeout_playspace_info.alignX = "right";
  6380.     level.zombies_timeout_playspace_info.x = 100;
  6381.     level.zombies_timeout_playspace_info.y = 95;
  6382.     level.zombies_timeout_playspace_info.label ="Timeout(Playspace): ";
  6383.     level.zombies_timeout_playspace_info.fontscale = 1.2;
  6384.  
  6385.     level.zombie_player_killed_count_info = NewHudElem();
  6386.     level.zombie_player_killed_count_info.alignX = "right";
  6387.     level.zombie_player_killed_count_info.x = 100;
  6388.     level.zombie_player_killed_count_info.y = 110;
  6389.     level.zombie_player_killed_count_info.label = "Zombies killed by players: ";
  6390.     level.zombie_player_killed_count_info.fontscale = 1.2;
  6391.  
  6392.     level.zombie_trap_killed_count_info = NewHudElem();
  6393.     level.zombie_trap_killed_count_info.alignX = "right";
  6394.     level.zombie_trap_killed_count_info.x = 100;
  6395.     level.zombie_trap_killed_count_info.y = 125;
  6396.     level.zombie_trap_killed_count_info.label = "Zombies killed by traps: ";
  6397.     level.zombie_trap_killed_count_info.fontscale = 1.2;
  6398.  
  6399.     level.zombie_pathing_failed_info = NewHudElem();
  6400.     level.zombie_pathing_failed_info.alignX = "right";
  6401.     level.zombie_pathing_failed_info.x = 100;
  6402.     level.zombie_pathing_failed_info.y = 140;
  6403.     level.zombie_pathing_failed_info.label = "Pathing failed: ";
  6404.     level.zombie_pathing_failed_info.fontscale = 1.2;
  6405.    
  6406.    
  6407.     level.zombie_breadcrumb_failed_info = NewHudElem();
  6408.     level.zombie_breadcrumb_failed_info.alignX = "right";
  6409.     level.zombie_breadcrumb_failed_info.x = 100;
  6410.     level.zombie_breadcrumb_failed_info.y = 155;
  6411.     level.zombie_breadcrumb_failed_info.label = "Breadcrumbs failed: ";
  6412.     level.zombie_breadcrumb_failed_info.fontscale = 1.2;
  6413.    
  6414.    
  6415.     level.player_0_distance_traveled_info = NewHudElem();
  6416.     level.player_0_distance_traveled_info.alignX = "right";
  6417.     level.player_0_distance_traveled_info.x = 100;
  6418.     level.player_0_distance_traveled_info.y = 170;
  6419.     level.player_0_distance_traveled_info.label = "Player(0) Distance traveled: ";
  6420.     level.player_0_distance_traveled_info.fontscale = 1.2;
  6421.    
  6422. }
  6423.  
  6424. update_screen_stats()
  6425. {
  6426.     flag_wait("all_players_spawned");
  6427.     while(1)
  6428.     {
  6429.         wait(1);
  6430.        
  6431.         if(getdvarint("zombie_show_stats") == 0)
  6432.         {
  6433.             level.zombies_timeout_spawn_info.alpha = 0;
  6434.             level.zombies_timeout_playspace_info.alpha = 0;
  6435.             level.zombie_player_killed_count_info.alpha = 0;
  6436.             level.zombie_trap_killed_count_info.alpha = 0;
  6437.             level.zombie_pathing_failed_info.alpha = 0;
  6438.             level.zombie_breadcrumb_failed_info.alpha = 0;
  6439.             level.player_0_distance_traveled_info.alpha = 0;
  6440.             continue;
  6441.         }
  6442.         else
  6443.         {
  6444.             level.zombies_timeout_spawn_info.alpha = 1;
  6445.             level.zombies_timeout_playspace_info.alpha = 1;
  6446.             level.zombie_player_killed_count_info.alpha = 1;
  6447.             level.zombie_trap_killed_count_info.alpha = 1;
  6448.             level.zombie_pathing_failed_info.alpha = 1;
  6449.             level.zombie_breadcrumb_failed_info.alpha = 1;
  6450.             level.player_0_distance_traveled_info.alpha = 1;
  6451.            
  6452.             level.zombies_timeout_spawn_info setValue( level.zombies_timeout_spawn );
  6453.             level.zombies_timeout_playspace_info SetValue(level.zombies_timeout_playspace );
  6454.             level.zombie_player_killed_count_info SetValue( level.zombie_player_killed_count);
  6455.             level.zombie_trap_killed_count_info SetValue( level.zombie_trap_killed_count);
  6456.             level.zombie_pathing_failed_info SetValue( level.zombie_pathing_failed );
  6457.             level.zombie_breadcrumb_failed_info SetValue( level.zombie_breadcrumb_failed );    
  6458.             level.player_0_distance_traveled_info SetValue( get_players()[0].stats["distance_traveled"] );
  6459.         }
  6460.     }
  6461. }
  6462.  
  6463.  
  6464. register_sidequest( id, solo_stat, solo_collectible, coop_stat, coop_collectible )
  6465. {
  6466.     if ( !IsDefined( level.zombie_sidequest_solo_stat ) )
  6467.     {
  6468.         level.zombie_sidequest_previously_completed = [];
  6469.         level.zombie_sidequest_solo_stat = [];
  6470.         level.zombie_sidequest_solo_collectible = [];
  6471.         level.zombie_sidequest_coop_stat = [];
  6472.         level.zombie_sidequest_coop_collectible = [];
  6473.     }
  6474.    
  6475.     level.zombie_sidequest_solo_stat[id] = solo_stat;
  6476.     level.zombie_sidequest_solo_collectible[id] = solo_collectible;
  6477.     level.zombie_sidequest_coop_stat[id] = coop_stat;
  6478.     level.zombie_sidequest_coop_collectible[id] = coop_collectible;
  6479.  
  6480.     flag_wait( "all_players_spawned" );
  6481.  
  6482.     level.zombie_sidequest_previously_completed[id] = false;
  6483.     if ( flag( "solo_game" ) )
  6484.     {
  6485.         if ( IsDefined( level.zombie_sidequest_solo_collectible[id] ) )
  6486.         {
  6487.             level.zombie_sidequest_previously_completed[id] = HasCollectible( level.zombie_sidequest_solo_collectible[id] );
  6488.         }
  6489.     }
  6490.     else
  6491.     {
  6492.         // don't do stats stuff if it's not an online game
  6493.         if ( level.systemLink || GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
  6494.         {
  6495.             if ( IsDefined( level.zombie_sidequest_coop_collectible[id] ) )
  6496.             {
  6497.                 level.zombie_sidequest_previously_completed[id] = HasCollectible( level.zombie_sidequest_coop_collectible[id] );
  6498.             }
  6499.             return;
  6500.         }
  6501.        
  6502.         if ( !isdefined( level.zombie_sidequest_coop_stat[id] ) )
  6503.         {
  6504.             return;
  6505.         }
  6506.  
  6507.         players = get_players();
  6508.         for ( i = 0; i < players.size; i++ )
  6509.         {
  6510.             if ( players[i] zombieStatGet( level.zombie_sidequest_coop_stat[id] ) )
  6511.             {
  6512.                 level.zombie_sidequest_previously_completed[id] = true;
  6513.                 return;
  6514.             }
  6515.         }
  6516.     }
  6517. }
  6518.  
  6519.  
  6520. is_sidequest_previously_completed(id)
  6521. {
  6522.     return is_true( level.zombie_sidequest_previously_completed[id] );
  6523. }
  6524.  
  6525.  
  6526. set_sidequest_completed(id)
  6527. {
  6528.     if ( maps\_cheat::is_cheating() || flag( "has_cheated" ) )
  6529.     {
  6530.         return;
  6531.     }
  6532.  
  6533.     if ( flag( "solo_game" ) )
  6534.     {
  6535.         client_notify_str = "SQS";
  6536.     }
  6537.     else
  6538.     {
  6539.         client_notify_str = "SQC";
  6540.     }
  6541.     clientnotify( client_notify_str ); // updates the collectibles value
  6542.  
  6543.     level notify( "zombie_sidequest_completed", id );
  6544.     level.zombie_sidequest_previously_completed[id] = true;
  6545.  
  6546.     // don't do stats stuff if it's not an online game
  6547.     if ( level.systemLink )
  6548.     {
  6549.         return;
  6550.     }
  6551.     if ( GetDvarInt( #"splitscreen_playerCount" ) == GetPlayers().size )
  6552.     {
  6553.         return;
  6554.     }
  6555.  
  6556.     players = get_players();
  6557.     for ( i = 0; i < players.size; i++ )
  6558.     {
  6559.         if ( isdefined( level.zombie_sidequest_solo_stat[id] ) )
  6560.         {
  6561.             players[i] zombieStatSet( level.zombie_sidequest_solo_stat[id], (players[i] zombieStatGet( level.zombie_sidequest_solo_stat[id] ) + 1) );
  6562.         }
  6563.  
  6564.         if ( !flag( "solo_game" ) && isdefined( level.zombie_sidequest_coop_stat[id] ) )
  6565.         {
  6566.             players[i] zombieStatSet( level.zombie_sidequest_coop_stat[id], (players[i] zombieStatGet( level.zombie_sidequest_coop_stat[id] ) + 1) );
  6567.         }
  6568.     }
  6569. }
Advertisement
Add Comment
Please, Sign In to add comment