burc_2004

_zm_afterlife.gsc

Oct 21st, 2015
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 62.92 KB | None | 0 0
  1. #include maps/mp/zombies/_zm_ai_basic;
  2. #include maps/mp/animscripts/shared;
  3. #include maps/mp/zombies/_zm_audio;
  4. #include maps/mp/zombies/_zm_zonemgr;
  5. #include maps/mp/zm_alcatraz_travel;
  6. #include maps/mp/gametypes_zm/_zm_gametype;
  7. #include maps/mp/zombies/_zm_equipment;
  8. #include maps/mp/zombies/_zm_weapons;
  9. #include maps/mp/zombies/_zm_clone;
  10. #include maps/mp/zombies/_zm_perk_electric_cherry;
  11. #include maps/mp/zombies/_zm_unitrigger;
  12. #include maps/mp/zombies/_zm;
  13. #include maps/mp/_visionset_mgr;
  14. #include maps/mp/zm_alcatraz_utility;
  15. #include maps/mp/zombies/_zm_laststand;
  16. #include maps/mp/gametypes_zm/_hud;
  17. #include maps/mp/gametypes_zm/_hud_util;
  18. #include maps/mp/zombies/_zm_utility;
  19. #include common_scripts/utility;
  20. #include maps/mp/_utility;
  21.  
  22. #using_animtree( "fxanim_props" );
  23.  
  24. init()
  25. {
  26.     level.zombiemode_using_afterlife = 1;
  27.     flag_init( "afterlife_start_over" );
  28.     level.afterlife_revive_tool = "syrette_afterlife_zm";
  29.     precacheitem( level.afterlife_revive_tool );
  30.     precachemodel( "drone_collision" );
  31.     maps/mp/_visionset_mgr::vsmgr_register_info( "visionset", "zm_afterlife", 9000, 120, 1, 1 );
  32.     maps/mp/_visionset_mgr::vsmgr_register_info( "overlay", "zm_afterlife_filter", 9000, 120, 1, 1 );
  33.     if ( isDefined( level.afterlife_player_damage_override ) )
  34.     {
  35.         maps/mp/zombies/_zm::register_player_damage_callback( level.afterlife_player_damage_override );
  36.     }
  37.     else
  38.     {
  39.         maps/mp/zombies/_zm::register_player_damage_callback( ::afterlife_player_damage_callback );
  40.     }
  41.     registerclientfield( "toplayer", "player_lives", 9000, 2, "int" );
  42.     registerclientfield( "toplayer", "player_in_afterlife", 9000, 1, "int" );
  43.     registerclientfield( "toplayer", "player_afterlife_mana", 9000, 5, "float" );
  44.     registerclientfield( "allplayers", "player_afterlife_fx", 9000, 1, "int" );
  45.     registerclientfield( "toplayer", "clientfield_afterlife_audio", 9000, 1, "int" );
  46.     registerclientfield( "toplayer", "player_afterlife_refill", 9000, 1, "int" );
  47.     registerclientfield( "scriptmover", "player_corpse_id", 9000, 3, "int" );
  48.     afterlife_load_fx();
  49.     level thread afterlife_hostmigration();
  50.     precachemodel( "c_zom_ghost_viewhands" );
  51.     precachemodel( "c_zom_hero_ghost_fb" );
  52.     precacheitem( "lightning_hands_zm" );
  53.     precachemodel( "p6_zm_al_shock_box_on" );
  54.     precacheshader( "waypoint_revive_afterlife" );
  55.     a_afterlife_interact = getentarray( "afterlife_interact", "targetname" );
  56.     array_thread( a_afterlife_interact, ::afterlife_interact_object_think );
  57.     level.zombie_spawners = getentarray( "zombie_spawner", "script_noteworthy" );
  58.     array_thread( level.zombie_spawners, ::add_spawn_function, ::afterlife_zombie_damage );
  59.     a_afterlife_triggers = getstructarray( "afterlife_trigger", "targetname" );
  60.     _a87 = a_afterlife_triggers;
  61.     _k87 = getFirstArrayKey( _a87 );
  62.     while ( isDefined( _k87 ) )
  63.     {
  64.         struct = _a87[ _k87 ];
  65.         afterlife_trigger_create( struct );
  66.         _k87 = getNextArrayKey( _a87, _k87 );
  67.     }
  68.     level.afterlife_interact_dist = 256;
  69.     level.is_player_valid_override = ::is_player_valid_afterlife;
  70.     level.can_revive = ::can_revive_override;
  71.     level.round_prestart_func = ::afterlife_start_zombie_logic;
  72.     level.custom_pap_validation = ::is_player_valid_afterlife;
  73.     level.player_out_of_playable_area_monitor_callback = ::player_out_of_playable_area;
  74.     level thread afterlife_gameover_cleanup();
  75.     level.afterlife_get_spawnpoint = ::afterlife_get_spawnpoint;
  76.     level.afterlife_zapped = ::afterlife_zapped;
  77.     level.afterlife_give_loadout = ::afterlife_give_loadout;
  78.     level.afterlife_save_loadout = ::afterlife_save_loadout;
  79. }
  80.  
  81. afterlife_gameover_cleanup()
  82. {
  83.     level waittill( "end_game" );
  84.     _a126 = getplayers();
  85.     _k126 = getFirstArrayKey( _a126 );
  86.     while ( isDefined( _k126 ) )
  87.     {
  88.         player = _a126[ _k126 ];
  89.         player.afterlife = 0;
  90.         player clientnotify( "end_game" );
  91.         player notify( "end_game" );
  92.         if ( isDefined( player.client_hint ) )
  93.         {
  94.             player.client_hint destroy();
  95.         }
  96.         _k126 = getNextArrayKey( _a126, _k126 );
  97.     }
  98.     wait 5;
  99.     _a141 = getplayers();
  100.     _k141 = getFirstArrayKey( _a141 );
  101.     while ( isDefined( _k141 ) )
  102.     {
  103.         player = _a141[ _k141 ];
  104.         if ( isDefined( level.optimise_for_splitscreen ) && !level.optimise_for_splitscreen )
  105.         {
  106.             maps/mp/_visionset_mgr::vsmgr_deactivate( "overlay", "zm_afterlife_filter", player );
  107.         }
  108.         _k141 = getNextArrayKey( _a141, _k141 );
  109.     }
  110. }
  111.  
  112. afterlife_load_fx()
  113. {
  114.     level._effect[ "afterlife_teleport" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_zmb_tport" );
  115.     level._effect[ "teleport_ball" ] = loadfx( "weapon/tomahawk/fx_tomahawk_trail_ug" );
  116.     level._effect[ "afterlife_kill_point_fx" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_suicide_area" );
  117.     level._effect[ "afterlife_enter" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_start" );
  118.     level._effect[ "afterlife_leave" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_player_revive" );
  119.     level._effect[ "afterlife_pixie_dust" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_pixies" );
  120.     level._effect[ "afterlife_corpse" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_player_down" );
  121.     level._effect[ "afterlife_damage" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_damage" );
  122.     level._effect[ "afterlife_ghost_fx" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_body" );
  123.     level._effect[ "afterlife_ghost_h_fx" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_head" );
  124.     level._effect[ "afterlife_ghost_arm_fx" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_arm" );
  125.     level._effect[ "afterlife_ghost_hand_fx" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_hand" );
  126.     level._effect[ "afterlife_ghost_hand_r_fx" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_hand_r" );
  127.     level._effect[ "afterlife_transition" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_transition" );
  128.     level._effect[ "fx_alcatraz_ghost_vm_wrist" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_vm_wrist" );
  129.     level._effect[ "fx_alcatraz_ghost_vm_wrist_r" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_vm_wrist_r" );
  130.     level._effect[ "fx_alcatraz_ghost_spectate" ] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_spec" );
  131. }
  132.  
  133. afterlife_start_zombie_logic()
  134. {
  135.     flag_wait( "start_zombie_round_logic" );
  136.     wait 0,5;
  137.     b_everyone_alive = 0;
  138.     while ( isDefined( b_everyone_alive ) && !b_everyone_alive )
  139.     {
  140.         b_everyone_alive = 1;
  141.         a_players = getplayers();
  142.         _a192 = a_players;
  143.         _k192 = getFirstArrayKey( _a192 );
  144.         while ( isDefined( _k192 ) )
  145.         {
  146.             player = _a192[ _k192 ];
  147.             if ( isDefined( player.afterlife ) && player.afterlife )
  148.             {
  149.                 b_everyone_alive = 0;
  150.                 wait 0,05;
  151.                 break;
  152.             }
  153.             else
  154.             {
  155.                 _k192 = getNextArrayKey( _a192, _k192 );
  156.             }
  157.         }
  158.     }
  159.     wait 0,5;
  160.     while ( level.intermission )
  161.     {
  162.         wait 0,05;
  163.     }
  164.     flag_set( "afterlife_start_over" );
  165.     wait 2;
  166.     array_func( getplayers(), ::afterlife_add );
  167. }
  168.  
  169. is_player_valid_afterlife( player )
  170. {
  171.     if ( isDefined( player.afterlife ) && player.afterlife )
  172.     {
  173.         return 0;
  174.     }
  175.     return 1;
  176. }
  177.  
  178. can_revive_override( revivee )
  179. {
  180.     if ( isDefined( self.afterlife ) && self.afterlife )
  181.     {
  182.         return 0;
  183.     }
  184.     return 1;
  185. }
  186.  
  187. player_out_of_playable_area()
  188. {
  189.     if ( isDefined( self.afterlife ) && self.afterlife )
  190.     {
  191.         return 0;
  192.     }
  193.     if ( isDefined( self.on_a_plane ) && self.on_a_plane )
  194.     {
  195.         return 0;
  196.     }
  197.     return 1;
  198. }
  199.  
  200. init_player()
  201. {
  202.     flag_wait( "initial_players_connected" );
  203.     if ( isDefined( level.is_forever_solo_game ) && level.is_forever_solo_game )
  204.     {
  205.         self.lives = 3;
  206.     }
  207.     else
  208.     {
  209.         self.lives = 1;
  210.     }
  211.     self setclientfieldtoplayer( "player_lives", self.lives );
  212.     self.afterlife = 0;
  213.     self.afterliferound = level.round_number;
  214.     self.afterlifedeaths = 0;
  215.     self thread afterlife_doors_close();
  216.     self thread afterlife_player_refill_watch();
  217. }
  218.  
  219. afterlife_remove( b_afterlife_death )
  220. {
  221.     if ( !isDefined( b_afterlife_death ) )
  222.     {
  223.         b_afterlife_death = 0;
  224.     }
  225.     if ( isDefined( b_afterlife_death ) && b_afterlife_death )
  226.     {
  227.         self.lives = 0;
  228.     }
  229.     else
  230.     {
  231.         if ( self.lives > 0 )
  232.         {
  233.             self.lives--;
  234.  
  235.         }
  236.     }
  237.     self notify( "sndLifeGone" );
  238.     self setclientfieldtoplayer( "player_lives", self.lives );
  239. }
  240.  
  241. afterlife_add()
  242. {
  243.     if ( isDefined( level.is_forever_solo_game ) && level.is_forever_solo_game )
  244.     {
  245.         if ( self.lives < 3 )
  246.         {
  247.             self.lives++;
  248.             self thread afterlife_add_fx();
  249.         }
  250.     }
  251.     else
  252.     {
  253.         if ( self.lives < 1 )
  254.         {
  255.             self.lives++;
  256.             self thread afterlife_add_fx();
  257.         }
  258.     }
  259.     self playsoundtoplayer( "zmb_afterlife_add", self );
  260.     self setclientfieldtoplayer( "player_lives", self.lives );
  261. }
  262.  
  263. afterlife_add_fx()
  264. {
  265.     if ( isDefined( self.afterlife ) && !self.afterlife )
  266.     {
  267.         self setclientfieldtoplayer( "player_afterlife_refill", 1 );
  268.         wait 3;
  269.         if ( isDefined( self.afterlife ) && !self.afterlife )
  270.         {
  271.             self setclientfieldtoplayer( "player_afterlife_refill", 0 );
  272.         }
  273.     }
  274. }
  275.  
  276. afterlife_player_refill_watch()
  277. {
  278.     self endon( "disconnect" );
  279.     self endon( "_zombie_game_over" );
  280.     level endon( "stage_final" );
  281.     while ( 1 )
  282.     {
  283.         level waittill( "end_of_round" );
  284.         wait 2;
  285.         self afterlife_add();
  286.         reset_all_afterlife_unitriggers();
  287.     }
  288. }
  289.  
  290. afterlife_player_damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime )
  291. {
  292.     if ( isDefined( eattacker ) )
  293.     {
  294.         if ( isDefined( eattacker.is_zombie ) && eattacker.is_zombie )
  295.         {
  296.             if ( isDefined( eattacker.custom_damage_func ) )
  297.             {
  298.                 idamage = eattacker [[ eattacker.custom_damage_func ]]( self );
  299.             }
  300.             else
  301.             {
  302.                 if ( isDefined( eattacker.meleedamage ) && smeansofdeath != "MOD_GRENADE_SPLASH" )
  303.                 {
  304.                     idamage = eattacker.meleedamage;
  305.                 }
  306.             }
  307.             if ( isDefined( self.afterlife ) && self.afterlife )
  308.             {
  309.                 self afterlife_reduce_mana( 10 );
  310.                 self clientnotify( "al_d" );
  311.                 return 0;
  312.             }
  313.         }
  314.     }
  315.     if ( isDefined( self.afterlife ) && self.afterlife )
  316.     {
  317.         return 0;
  318.     }
  319.     if ( isDefined( eattacker ) && isDefined( eattacker.is_zombie ) || eattacker.is_zombie && isplayer( eattacker ) )
  320.     {
  321.         if ( isDefined( self.hasriotshield ) && self.hasriotshield && isDefined( vdir ) )
  322.         {
  323.             item_dmg = 100;
  324.             if ( isDefined( eattacker.custom_item_dmg ) )
  325.             {
  326.                 item_dmg = eattacker.custom_item_dmg;
  327.             }
  328.             if ( isDefined( self.hasriotshieldequipped ) && self.hasriotshieldequipped )
  329.             {
  330.                 if ( self player_shield_facing_attacker( vdir, 0,2 ) && isDefined( self.player_shield_apply_damage ) )
  331.                 {
  332.                     self [[ self.player_shield_apply_damage ]]( item_dmg, 0 );
  333.                     return 0;
  334.                 }
  335.             }
  336.             else
  337.             {
  338.                 if ( !isDefined( self.riotshieldentity ) )
  339.                 {
  340.                     if ( !self player_shield_facing_attacker( vdir, -0,2 ) && isDefined( self.player_shield_apply_damage ) )
  341.                     {
  342.                         self [[ self.player_shield_apply_damage ]]( item_dmg, 0 );
  343.                         return 0;
  344.                     }
  345.                 }
  346.             }
  347.         }
  348.     }
  349.     if ( smeansofdeath != "MOD_PROJECTILE" && smeansofdeath != "MOD_PROJECTILE_SPLASH" || smeansofdeath == "MOD_GRENADE" && smeansofdeath == "MOD_GRENADE_SPLASH" )
  350.     {
  351.         if ( sweapon == "blundersplat_explosive_dart_zm" )
  352.         {
  353.             if ( self hasperk( "specialty_flakjacket" ) )
  354.             {
  355.                 self.use_adjusted_grenade_damage = 1;
  356.                 idamage = 0;
  357.             }
  358.             if ( isalive( self ) && isDefined( self.is_zombie ) && !self.is_zombie )
  359.             {
  360.                 self.use_adjusted_grenade_damage = 1;
  361.                 idamage = 10;
  362.             }
  363.         }
  364.         else
  365.         {
  366.             if ( self hasperk( "specialty_flakjacket" ) )
  367.             {
  368.                 return 0;
  369.             }
  370.             if ( self.health > 75 && isDefined( self.is_zombie ) && !self.is_zombie )
  371.             {
  372.                 idamage = 75;
  373.             }
  374.         }
  375.     }
  376.     if ( sweapon == "tower_trap_zm" || sweapon == "tower_trap_upgraded_zm" )
  377.     {
  378.         self.use_adjusted_grenade_damage = 1;
  379.         return 0;
  380.     }
  381.     if ( idamage >= self.health && isDefined( level.intermission ) && !level.intermission )
  382.     {
  383.         if ( self.lives > 0 && isDefined( self.afterlife ) && !self.afterlife )
  384.         {
  385.             self playsoundtoplayer( "zmb_afterlife_death", self );
  386.             self afterlife_remove();
  387.             self.afterlife = 1;
  388.             self thread afterlife_laststand();
  389.             if ( self.health <= 1 )
  390.             {
  391.                 return 0;
  392.             }
  393.             else
  394.             {
  395.                 idamage = self.health - 1;
  396.             }
  397.         }
  398.         else
  399.         {
  400.             self thread last_stand_conscience_vo();
  401.         }
  402.     }
  403.     return idamage;
  404. }
  405.  
  406. afterlife_enter()
  407. {
  408.     if ( !isDefined( self.afterlife_visionset ) || self.afterlife_visionset == 0 )
  409.     {
  410.         maps/mp/_visionset_mgr::vsmgr_activate( "visionset", "zm_afterlife", self );
  411.         if ( isDefined( level.optimise_for_splitscreen ) && !level.optimise_for_splitscreen )
  412.         {
  413.             maps/mp/_visionset_mgr::vsmgr_activate( "overlay", "zm_afterlife_filter", self );
  414.         }
  415.         self.afterlife_visionset = 1;
  416.     }
  417.     self enableafterlife();
  418.     self.str_living_model = self.model;
  419.     self.str_living_view = self getviewmodel();
  420.     self setmodel( "c_zom_hero_ghost_fb" );
  421.     self setviewmodel( "c_zom_ghost_viewhands" );
  422.     self thread afterlife_doors_open();
  423.     self setclientfieldtoplayer( "player_in_afterlife", 1 );
  424.     self setclientfield( "player_afterlife_fx", 1 );
  425.     self afterlife_create_mana_bar( self.e_afterlife_corpse );
  426.     if ( !isDefined( self.keep_perks ) && flag( "afterlife_start_over" ) )
  427.     {
  428.         self increment_downed_stat();
  429.     }
  430.     a_afterlife_triggers = getstructarray( "afterlife_trigger", "targetname" );
  431.     _a534 = a_afterlife_triggers;
  432.     _k534 = getFirstArrayKey( _a534 );
  433.     while ( isDefined( _k534 ) )
  434.     {
  435.         struct = _a534[ _k534 ];
  436.         struct.unitrigger_stub maps/mp/zombies/_zm_unitrigger::run_visibility_function_for_all_triggers();
  437.         _k534 = getNextArrayKey( _a534, _k534 );
  438.     }
  439.     a_exterior_goals = getstructarray( "exterior_goal", "targetname" );
  440.     _a541 = a_exterior_goals;
  441.     _k541 = getFirstArrayKey( _a541 );
  442.     while ( isDefined( _k541 ) )
  443.     {
  444.         struct = _a541[ _k541 ];
  445.         if ( isDefined( struct.unitrigger_stub ) )
  446.         {
  447.             struct.unitrigger_stub maps/mp/zombies/_zm_unitrigger::run_visibility_function_for_all_triggers();
  448.         }
  449.         _k541 = getNextArrayKey( _a541, _k541 );
  450.     }
  451. }
  452.  
  453. afterlife_leave( b_revived )
  454. {
  455.     if ( !isDefined( b_revived ) )
  456.     {
  457.         b_revived = 1;
  458.     }
  459.     self clientnotify( "al_t" );
  460.     if ( isDefined( self.afterlife_visionset ) && self.afterlife_visionset )
  461.     {
  462.         maps/mp/_visionset_mgr::vsmgr_deactivate( "visionset", "zm_afterlife", self );
  463.         if ( isDefined( level.optimise_for_splitscreen ) && !level.optimise_for_splitscreen )
  464.         {
  465.             maps/mp/_visionset_mgr::vsmgr_deactivate( "overlay", "zm_afterlife_filter", self );
  466.         }
  467.         self.afterlife_visionset = 0;
  468.     }
  469.     self disableafterlife();
  470.     self.dontspeak = 0;
  471.     self thread afterlife_doors_close();
  472.     self.health = self.maxhealth;
  473.     self setclientfieldtoplayer( "player_in_afterlife", 0 );
  474.     self setclientfield( "player_afterlife_fx", 0 );
  475.     self setclientfieldtoplayer( "clientfield_afterlife_audio", 0 );
  476.     self maps/mp/zombies/_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 );
  477.     self allowstand( 1 );
  478.     self allowcrouch( 1 );
  479.     self allowprone( 1 );
  480.     self setmodel( self.str_living_model );
  481.     self setviewmodel( self.str_living_view );
  482.     if ( self.e_afterlife_corpse.revivetrigger.origin != self.e_afterlife_corpse.origin )
  483.     {
  484.         self setorigin( self.e_afterlife_corpse.revivetrigger.origin );
  485.     }
  486.     else
  487.     {
  488.         self setorigin( self.e_afterlife_corpse.origin );
  489.     }
  490.     while ( isDefined( level.e_gondola ) )
  491.     {
  492.         a_gondola_doors_gates = get_gondola_doors_and_gates();
  493.         i = 0;
  494.         while ( i < a_gondola_doors_gates.size )
  495.         {
  496.             if ( self.e_afterlife_corpse istouching( a_gondola_doors_gates[ i ] ) )
  497.             {
  498.                 if ( isDefined( level.e_gondola.is_moving ) && level.e_gondola.is_moving )
  499.                 {
  500.                     str_location = level.e_gondola.destination;
  501.                 }
  502.                 else
  503.                 {
  504.                     str_location = level.e_gondola.location;
  505.                 }
  506.                 a_s_orgs = getstructarray( "gondola_dropped_parts_" + str_location, "targetname" );
  507.                 _a617 = a_s_orgs;
  508.                 _k617 = getFirstArrayKey( _a617 );
  509.                 while ( isDefined( _k617 ) )
  510.                 {
  511.                     struct = _a617[ _k617 ];
  512.                     if ( !positionwouldtelefrag( struct.origin ) )
  513.                     {
  514.                         self setorigin( struct.origin );
  515.                         break;
  516.                     }
  517.                     else
  518.                     {
  519.                         _k617 = getNextArrayKey( _a617, _k617 );
  520.                     }
  521.                 }
  522.             }
  523.             else i++;
  524.         }
  525.     }
  526.     self setplayerangles( self.e_afterlife_corpse.angles );
  527.     self.afterlife = 0;
  528.     self afterlife_laststand_cleanup( self.e_afterlife_corpse );
  529.     if ( isDefined( b_revived ) && !b_revived )
  530.     {
  531.         self afterlife_remove( 1 );
  532.         self dodamage( 1000, self.origin );
  533.     }
  534.     reset_all_afterlife_unitriggers();
  535. }
  536.  
  537. afterlife_laststand( b_electric_chair )
  538. {
  539.     if ( !isDefined( b_electric_chair ) )
  540.     {
  541.         b_electric_chair = 0;
  542.     }
  543.     self endon( "disconnect" );
  544.     self endon( "afterlife_bleedout" );
  545.     level endon( "end_game" );
  546.     if ( isDefined( level.afterlife_laststand_override ) )
  547.     {
  548.         self thread [[ level.afterlife_laststand_override ]]( b_electric_chair );
  549.         return;
  550.     }
  551.     self.dontspeak = 1;
  552.     self.health = 1000;
  553.     b_has_electric_cherry = 0;
  554.     if ( self hasperk( "specialty_grenadepulldeath" ) )
  555.     {
  556.         b_has_electric_cherry = 1;
  557.     }
  558.     self [[ level.afterlife_save_loadout ]]();
  559.     self afterlife_fake_death();
  560.     if ( isDefined( b_electric_chair ) && !b_electric_chair )
  561.     {
  562.         wait 1;
  563.     }
  564.     if ( isDefined( b_has_electric_cherry ) && b_has_electric_cherry && isDefined( b_electric_chair ) && !b_electric_chair )
  565.     {
  566.         self maps/mp/zombies/_zm_perk_electric_cherry::electric_cherry_laststand();
  567.         wait 2;
  568.     }
  569.     self setclientfieldtoplayer( "clientfield_afterlife_audio", 1 );
  570.     if ( flag( "afterlife_start_over" ) )
  571.     {
  572.         self clientnotify( "al_t" );
  573.         wait 1;
  574.         self thread fadetoblackforxsec( 0, 1, 0,5, 0,5, "white" );
  575.         wait 0,5;
  576.     }
  577.     self ghost();
  578.     self.e_afterlife_corpse = self afterlife_spawn_corpse();
  579.     self thread afterlife_clean_up_on_disconnect();
  580.     self notify( "player_fake_corpse_created" );
  581.     self afterlife_fake_revive();
  582.     self afterlife_enter();
  583.     self.e_afterlife_corpse setclientfield( "player_corpse_id", self getentitynumber() + 1 );
  584.     wait 0,5;
  585.     self show();
  586.     if ( isDefined( self.hostmigrationcontrolsfrozen ) && !self.hostmigrationcontrolsfrozen )
  587.     {
  588.         self freezecontrols( 0 );
  589.     }
  590.     self disableinvulnerability();
  591.     self.e_afterlife_corpse waittill( "player_revived", e_reviver );
  592.     self notify( "player_revived" );
  593.     self seteverhadweaponall( 1 );
  594.     self enableinvulnerability();
  595.     self.afterlife_revived = 1;
  596.     playsoundatposition( "zmb_afterlife_spawn_leave", self.e_afterlife_corpse.origin );
  597.     self afterlife_leave();
  598.     self thread afterlife_revive_invincible();
  599.     self playsound( "zmb_afterlife_revived_gasp" );
  600. }
  601.  
  602. afterlife_clean_up_on_disconnect()
  603. {
  604.     e_corpse = self.e_afterlife_corpse;
  605.     e_corpse endon( "death" );
  606.     self waittill( "disconnect" );
  607.     if ( isDefined( e_corpse.revivetrigger ) )
  608.     {
  609.         e_corpse notify( "stop_revive_trigger" );
  610.         e_corpse.revivetrigger delete();
  611.         e_corpse.revivetrigger = undefined;
  612.     }
  613.     e_corpse setclientfield( "player_corpse_id", 0 );
  614.     e_corpse notify( "disconnect" );
  615.     wait_network_frame();
  616.     wait_network_frame();
  617.     e_corpse delete();
  618. }
  619.  
  620. afterlife_revive_invincible()
  621. {
  622.     self endon( "disconnect" );
  623.     wait 2;
  624.     self disableinvulnerability();
  625.     self seteverhadweaponall( 0 );
  626.     self.afterlife_revived = undefined;
  627. }
  628.  
  629. afterlife_laststand_cleanup( corpse )
  630. {
  631.     self [[ level.afterlife_give_loadout ]]();
  632.     self afterlife_corpse_cleanup( corpse );
  633. }
  634.  
  635. afterlife_create_mana_bar( corpse )
  636. {
  637.     if ( self.afterliferound == level.round_number )
  638.     {
  639.         if ( !isDefined( self.keep_perks ) || self.afterlifedeaths == 0 )
  640.         {
  641.             self.afterlifedeaths++;
  642.         }
  643.     }
  644.     else
  645.     {
  646.         self.afterliferound = level.round_number;
  647.         self.afterlifedeaths = 1;
  648.     }
  649.     self.manacur = 200;
  650.     self thread afterlife_mana_watch( corpse );
  651.     self thread afterlife_lightning_watch( corpse );
  652.     self thread afterlife_jump_watch( corpse );
  653. }
  654.  
  655. afterlife_infinite_mana( b_infinite )
  656. {
  657.     if ( !isDefined( b_infinite ) )
  658.     {
  659.         b_infinite = 1;
  660.     }
  661.     if ( isDefined( b_infinite ) && b_infinite )
  662.     {
  663.         self.infinite_mana = 1;
  664.     }
  665.     else
  666.     {
  667.         self.infinite_mana = 0;
  668.     }
  669. }
  670.  
  671. afterlife_mana_watch( corpse )
  672. {
  673.     self endon( "disconnect" );
  674.     corpse endon( "player_revived" );
  675.     while ( self.manacur > 0 )
  676.     {
  677.         wait 0,05;
  678.         self afterlife_reduce_mana( 0,05 * self.afterlifedeaths * 3 );
  679.         if ( self.manacur < 0 )
  680.         {
  681.             self.manacur = 0;
  682.         }
  683.         n_mapped_mana = linear_map( self.manacur, 0, 200, 0, 1 );
  684.         self setclientfieldtoplayer( "player_afterlife_mana", n_mapped_mana );
  685.     }
  686.     while ( isDefined( corpse.revivetrigger ) )
  687.     {
  688.         while ( corpse.revivetrigger.beingrevived )
  689.         {
  690.             wait 0,05;
  691.         }
  692.     }
  693.     corpse notify( "stop_revive_trigger" );
  694.     self thread fadetoblackforxsec( 0, 0,5, 0,5, 0,5, "black" );
  695.     wait 0,5;
  696.     self notify( "out_of_mana" );
  697.     self afterlife_leave( 0 );
  698. }
  699.  
  700. afterlife_doors_open()
  701. {
  702.     n_network_sent = 0;
  703.     a_show = getentarray( "afterlife_show", "targetname" );
  704.     a_show = arraycombine( a_show, getentarray( "afterlife_prop", "script_noteworthy" ), 0, 0 );
  705.     _a888 = a_show;
  706.     _k888 = getFirstArrayKey( _a888 );
  707.     while ( isDefined( _k888 ) )
  708.     {
  709.         ent = _a888[ _k888 ];
  710.         n_network_sent++;
  711.         if ( n_network_sent > 10 )
  712.         {
  713.             n_network_sent = 0;
  714.             wait_network_frame();
  715.         }
  716.         if ( isDefined( ent ) )
  717.         {
  718.             ent setvisibletoplayer( self );
  719.         }
  720.         _k888 = getNextArrayKey( _a888, _k888 );
  721.     }
  722.     a_hide = getentarray( "afterlife_door", "targetname" );
  723.     a_hide = arraycombine( a_hide, getentarray( "zombie_door", "targetname" ), 0, 0 );
  724.     a_hide = arraycombine( a_hide, getentarray( "quest_trigger", "script_noteworthy" ), 0, 0 );
  725.     a_hide = arraycombine( a_hide, getentarray( "trap_trigger", "script_noteworthy" ), 0, 0 );
  726.     a_hide = arraycombine( a_hide, getentarray( "travel_trigger", "script_noteworthy" ), 0, 0 );
  727.     _a907 = a_hide;
  728.     _k907 = getFirstArrayKey( _a907 );
  729.     while ( isDefined( _k907 ) )
  730.     {
  731.         ent = _a907[ _k907 ];
  732.         n_network_sent++;
  733.         if ( n_network_sent > 10 )
  734.         {
  735.             n_network_sent = 0;
  736.             wait_network_frame();
  737.         }
  738.         if ( isDefined( ent ) )
  739.         {
  740.             ent setinvisibletoplayer( self );
  741.         }
  742.         _k907 = getNextArrayKey( _a907, _k907 );
  743.     }
  744.     while ( isDefined( self.claymores ) )
  745.     {
  746.         _a924 = self.claymores;
  747.         _k924 = getFirstArrayKey( _a924 );
  748.         while ( isDefined( _k924 ) )
  749.         {
  750.             claymore = _a924[ _k924 ];
  751.             if ( isDefined( claymore.pickuptrigger ) )
  752.             {
  753.                 claymore.pickuptrigger setinvisibletoplayer( self );
  754.             }
  755.             _k924 = getNextArrayKey( _a924, _k924 );
  756.         }
  757.     }
  758. }
  759.  
  760. afterlife_doors_close()
  761. {
  762.     n_network_sent = 0;
  763.     a_hide = getentarray( "afterlife_show", "targetname" );
  764.     a_hide = arraycombine( a_hide, getentarray( "afterlife_prop", "script_noteworthy" ), 0, 0 );
  765.     _a943 = a_hide;
  766.     _k943 = getFirstArrayKey( _a943 );
  767.     while ( isDefined( _k943 ) )
  768.     {
  769.         ent = _a943[ _k943 ];
  770.         n_network_sent++;
  771.         if ( n_network_sent > 10 )
  772.         {
  773.             n_network_sent = 0;
  774.             wait_network_frame();
  775.         }
  776.         if ( isDefined( ent ) )
  777.         {
  778.             ent setinvisibletoplayer( self );
  779.         }
  780.         _k943 = getNextArrayKey( _a943, _k943 );
  781.     }
  782.     a_show = getentarray( "afterlife_door", "targetname" );
  783.     a_show = arraycombine( a_show, getentarray( "zombie_door", "targetname" ), 0, 0 );
  784.     a_show = arraycombine( a_show, getentarray( "quest_trigger", "script_noteworthy" ), 0, 0 );
  785.     a_show = arraycombine( a_show, getentarray( "trap_trigger", "script_noteworthy" ), 0, 0 );
  786.     a_show = arraycombine( a_show, getentarray( "travel_trigger", "script_noteworthy" ), 0, 0 );
  787.     _a962 = a_show;
  788.     _k962 = getFirstArrayKey( _a962 );
  789.     while ( isDefined( _k962 ) )
  790.     {
  791.         ent = _a962[ _k962 ];
  792.         n_network_sent++;
  793.         if ( n_network_sent > 10 )
  794.         {
  795.             n_network_sent = 0;
  796.             wait_network_frame();
  797.         }
  798.         if ( isDefined( ent ) )
  799.         {
  800.             ent setvisibletoplayer( self );
  801.         }
  802.         _k962 = getNextArrayKey( _a962, _k962 );
  803.     }
  804.     while ( isDefined( self.claymores ) )
  805.     {
  806.         _a979 = self.claymores;
  807.         _k979 = getFirstArrayKey( _a979 );
  808.         while ( isDefined( _k979 ) )
  809.         {
  810.             claymore = _a979[ _k979 ];
  811.             if ( isDefined( claymore.pickuptrigger ) )
  812.             {
  813.                 claymore.pickuptrigger setvisibletoplayer( self );
  814.             }
  815.             _k979 = getNextArrayKey( _a979, _k979 );
  816.         }
  817.     }
  818. }
  819.  
  820. afterlife_corpse_cleanup( corpse )
  821. {
  822.     playsoundatposition( "zmb_afterlife_revived", corpse.origin );
  823.     if ( isDefined( corpse.revivetrigger ) )
  824.     {
  825.         corpse notify( "stop_revive_trigger" );
  826.         corpse.revivetrigger delete();
  827.         corpse.revivetrigger = undefined;
  828.     }
  829.     corpse setclientfield( "player_corpse_id", 0 );
  830.     corpse afterlife_corpse_remove_pois();
  831.     wait_network_frame();
  832.     wait_network_frame();
  833.     corpse delete();
  834.     self.e_afterlife_corpse = undefined;
  835. }
  836.  
  837. afterlife_spawn_corpse()
  838. {
  839.     if ( isDefined( self.is_on_gondola ) && self.is_on_gondola && level.e_gondola.destination == "roof" )
  840.     {
  841.         corpse = maps/mp/zombies/_zm_clone::spawn_player_clone( self, self.origin, undefined );
  842.     }
  843.     else
  844.     {
  845.         trace_start = self.origin;
  846.         trace_end = self.origin + vectorScale( ( 0, 0, 1 ), 500 );
  847.         corpse_trace = playerphysicstrace( trace_start, trace_end );
  848.         corpse = maps/mp/zombies/_zm_clone::spawn_player_clone( self, corpse_trace, undefined );
  849.     }
  850.     corpse.angles = self.angles;
  851.     corpse.ignoreme = 1;
  852.     corpse maps/mp/zombies/_zm_clone::clone_give_weapon( "m1911_zm" );
  853.     corpse maps/mp/zombies/_zm_clone::clone_animate( "afterlife" );
  854.     corpse.revive_hud = self afterlife_revive_hud_create();
  855.     corpse thread afterlife_revive_trigger_spawn();
  856.     if ( flag( "solo_game" ) )
  857.     {
  858.         corpse thread afterlife_corpse_create_pois();
  859.     }
  860.     return corpse;
  861. }
  862.  
  863. afterlife_corpse_create_pois()
  864. {
  865.     n_attractors = ceil( get_current_zombie_count() / 3 );
  866.     if ( n_attractors < 4 )
  867.     {
  868.         n_attractors = 4;
  869.     }
  870.     a_nodes = afterlife_corpse_get_array_poi_positions();
  871.     self.pois = [];
  872.     while ( isDefined( a_nodes ) && a_nodes.size > 3 )
  873.     {
  874.         i = 0;
  875.         while ( i < 3 )
  876.         {
  877.             self.pois[ i ] = afterlife_corpse_create_poi( a_nodes[ i ].origin, n_attractors );
  878.             wait 0,05;
  879.             i++;
  880.         }
  881.     }
  882. }
  883.  
  884. afterlife_corpse_create_poi( v_origin, n_attractors )
  885. {
  886.     e_poi = spawn( "script_origin", v_origin );
  887.     e_poi create_zombie_point_of_interest( 10000, 24, 5000, 1 );
  888.     e_poi thread create_zombie_point_of_interest_attractor_positions();
  889. /#
  890.     e_poi thread print3d_ent( "Corpse POI" );
  891. #/
  892.     return e_poi;
  893. }
  894.  
  895. afterlife_corpse_remove_pois()
  896. {
  897.     if ( !isDefined( self.pois ) )
  898.     {
  899.         return;
  900.     }
  901.     i = 0;
  902.     while ( i < self.pois.size )
  903.     {
  904.         remove_poi_attractor( self.pois[ i ] );
  905.         self.pois[ i ] delete();
  906.         i++;
  907.     }
  908.     self.pois = undefined;
  909. }
  910.  
  911. afterlife_corpse_get_array_poi_positions()
  912. {
  913.     n_ideal_dist_sq = 490000;
  914.     a_nodes = getanynodearray( self.origin, 1200 );
  915.     i = 0;
  916.     while ( i < a_nodes.size )
  917.     {
  918.         if ( !a_nodes[ i ] is_valid_teleport_node() )
  919.         {
  920.         }
  921.         i++;
  922.     }
  923.     a_nodes = remove_undefined_from_array( a_nodes );
  924.     return array_randomize( a_nodes );
  925. }
  926.  
  927. afterlife_revive_hud_create()
  928. {
  929.     self.revive_hud = newclienthudelem( self );
  930.     self.revive_hud.alignx = "center";
  931.     self.revive_hud.aligny = "middle";
  932.     self.revive_hud.horzalign = "center";
  933.     self.revive_hud.vertalign = "bottom";
  934.     self.revive_hud.y = -160;
  935.     self.revive_hud.foreground = 1;
  936.     self.revive_hud.font = "default";
  937.     self.revive_hud.fontscale = 1,5;
  938.     self.revive_hud.alpha = 0;
  939.     self.revive_hud.color = ( 0, 0, 1 );
  940.     self.revive_hud.hidewheninmenu = 1;
  941.     self.revive_hud settext( "" );
  942.     return self.revive_hud;
  943. }
  944.  
  945. afterlife_revive_trigger_spawn()
  946. {
  947.     radius = getDvarInt( "revive_trigger_radius" );
  948.     self.revivetrigger = spawn( "trigger_radius", ( 0, 0, 1 ), 0, radius, radius );
  949.     self.revivetrigger sethintstring( "" );
  950.     self.revivetrigger setcursorhint( "HINT_NOICON" );
  951.     self.revivetrigger setmovingplatformenabled( 1 );
  952.     self.revivetrigger enablelinkto();
  953.     self.revivetrigger.origin = self.origin;
  954.     self.revivetrigger linkto( self );
  955.     self.revivetrigger.beingrevived = 0;
  956.     self.revivetrigger.createtime = getTime();
  957.     self thread afterlife_revive_trigger_think();
  958. }
  959.  
  960. afterlife_revive_trigger_think()
  961. {
  962.     self endon( "disconnect" );
  963.     self endon( "stop_revive_trigger" );
  964.     self endon( "death" );
  965.     wait 1;
  966.     while ( 1 )
  967.     {
  968.         wait 0,1;
  969.         self.revivetrigger sethintstring( "" );
  970.         players = get_players();
  971.         i = 0;
  972.         while ( i < players.size )
  973.         {
  974.             if ( players[ i ] afterlife_can_revive( self ) )
  975.             {
  976.                 self.revivetrigger setrevivehintstring( &"GAME_BUTTON_TO_REVIVE_PLAYER", self.team );
  977.                 break;
  978.             }
  979.             else
  980.             {
  981.                 i++;
  982.             }
  983.         }
  984.         i = 0;
  985.         while ( i < players.size )
  986.         {
  987.             reviver = players[ i ];
  988.             if ( self == reviver || !reviver is_reviving_afterlife( self ) )
  989.             {
  990.                 i++;
  991.                 continue;
  992.             }
  993.             else
  994.             {
  995.                 gun = reviver getcurrentweapon();
  996. /#
  997.                 assert( isDefined( gun ) );
  998. #/
  999.                 if ( gun == level.revive_tool || gun == level.afterlife_revive_tool )
  1000.                 {
  1001.                     i++;
  1002.                     continue;
  1003.                 }
  1004.                 else
  1005.                 {
  1006.                     if ( isDefined( reviver.afterlife ) && reviver.afterlife )
  1007.                     {
  1008.                         reviver giveweapon( level.afterlife_revive_tool );
  1009.                         reviver switchtoweapon( level.afterlife_revive_tool );
  1010.                         reviver setweaponammostock( level.afterlife_revive_tool, 1 );
  1011.                     }
  1012.                     else
  1013.                     {
  1014.                         reviver giveweapon( level.revive_tool );
  1015.                         reviver switchtoweapon( level.revive_tool );
  1016.                         reviver setweaponammostock( level.revive_tool, 1 );
  1017.                     }
  1018.                     revive_success = reviver afterlife_revive_do_revive( self, gun );
  1019.                     reviver revive_give_back_weapons( gun );
  1020.                     if ( isplayer( self ) )
  1021.                     {
  1022.                         self allowjump( 1 );
  1023.                     }
  1024.                     self.laststand = undefined;
  1025.                     if ( revive_success )
  1026.                     {
  1027.                         self thread revive_success( reviver );
  1028.                         self cleanup_suicide_hud();
  1029.                         return;
  1030.                     }
  1031.                 }
  1032.             }
  1033.             i++;
  1034.         }
  1035.     }
  1036. }
  1037.  
  1038. afterlife_can_revive( revivee )
  1039. {
  1040.     if ( isDefined( self.afterlife ) && self.afterlife && isDefined( self.e_afterlife_corpse ) && self.e_afterlife_corpse != revivee )
  1041.     {
  1042.         return 0;
  1043.     }
  1044.     if ( !isDefined( revivee.revivetrigger ) )
  1045.     {
  1046.         return 0;
  1047.     }
  1048.     if ( !isalive( self ) )
  1049.     {
  1050.         return 0;
  1051.     }
  1052.     if ( self player_is_in_laststand() )
  1053.     {
  1054.         return 0;
  1055.     }
  1056.     if ( self.team != revivee.team )
  1057.     {
  1058.         return 0;
  1059.     }
  1060.     if ( self has_powerup_weapon() )
  1061.     {
  1062.         return 0;
  1063.     }
  1064.     ignore_sight_checks = 0;
  1065.     ignore_touch_checks = 0;
  1066.     if ( isDefined( level.revive_trigger_should_ignore_sight_checks ) )
  1067.     {
  1068.         ignore_sight_checks = [[ level.revive_trigger_should_ignore_sight_checks ]]( self );
  1069.         if ( ignore_sight_checks && isDefined( revivee.revivetrigger.beingrevived ) && revivee.revivetrigger.beingrevived == 1 )
  1070.         {
  1071.             ignore_touch_checks = 1;
  1072.         }
  1073.     }
  1074.     if ( !ignore_touch_checks )
  1075.     {
  1076.         if ( !self istouching( revivee.revivetrigger ) )
  1077.         {
  1078.             return 0;
  1079.         }
  1080.     }
  1081.     if ( !ignore_sight_checks )
  1082.     {
  1083.         if ( !self is_facing( revivee ) )
  1084.         {
  1085.             return 0;
  1086.         }
  1087.         if ( !sighttracepassed( self.origin + vectorScale( ( 0, 0, 1 ), 50 ), revivee.origin + vectorScale( ( 0, 0, 1 ), 30 ), 0, undefined ) )
  1088.         {
  1089.             return 0;
  1090.         }
  1091.     }
  1092.     return 1;
  1093. }
  1094.  
  1095. afterlife_revive_do_revive( playerbeingrevived, revivergun )
  1096. {
  1097. /#
  1098.     assert( self is_reviving_afterlife( playerbeingrevived ) );
  1099. #/
  1100.     revivetime = 3;
  1101.     playloop = 0;
  1102.     if ( isDefined( self.afterlife ) && self.afterlife )
  1103.     {
  1104.         playloop = 1;
  1105.         revivetime = 1;
  1106.     }
  1107.     timer = 0;
  1108.     revived = 0;
  1109.     playerbeingrevived.revivetrigger.beingrevived = 1;
  1110.     playerbeingrevived.revive_hud settext( &"GAME_PLAYER_IS_REVIVING_YOU", self );
  1111.     playerbeingrevived revive_hud_show_n_fade( 3 );
  1112.     playerbeingrevived.revivetrigger sethintstring( "" );
  1113.     if ( isplayer( playerbeingrevived ) )
  1114.     {
  1115.         playerbeingrevived startrevive( self );
  1116.     }
  1117.     if ( !isDefined( self.reviveprogressbar ) )
  1118.     {
  1119.         self.reviveprogressbar = self createprimaryprogressbar();
  1120.     }
  1121.     if ( !isDefined( self.revivetexthud ) )
  1122.     {
  1123.         self.revivetexthud = newclienthudelem( self );
  1124.     }
  1125.     self thread revive_clean_up_on_gameover();
  1126.     self thread laststand_clean_up_on_disconnect( playerbeingrevived, revivergun );
  1127.     if ( !isDefined( self.is_reviving_any ) )
  1128.     {
  1129.         self.is_reviving_any = 0;
  1130.     }
  1131.     self.is_reviving_any++;
  1132.     self thread laststand_clean_up_reviving_any( playerbeingrevived );
  1133.     self.reviveprogressbar updatebar( 0,01, 1 / revivetime );
  1134.     self.revivetexthud.alignx = "center";
  1135.     self.revivetexthud.aligny = "middle";
  1136.     self.revivetexthud.horzalign = "center";
  1137.     self.revivetexthud.vertalign = "bottom";
  1138.     self.revivetexthud.y = -113;
  1139.     if ( self issplitscreen() )
  1140.     {
  1141.         self.revivetexthud.y = -347;
  1142.     }
  1143.     self.revivetexthud.foreground = 1;
  1144.     self.revivetexthud.font = "default";
  1145.     self.revivetexthud.fontscale = 1,8;
  1146.     self.revivetexthud.alpha = 1;
  1147.     self.revivetexthud.color = ( 0, 0, 1 );
  1148.     self.revivetexthud.hidewheninmenu = 1;
  1149.     if ( isDefined( self.pers_upgrades_awarded[ "revive" ] ) && self.pers_upgrades_awarded[ "revive" ] )
  1150.     {
  1151.         self.revivetexthud.color = ( 0,5, 0,5, 1 );
  1152.     }
  1153.     self.revivetexthud settext( &"GAME_REVIVING" );
  1154.     self thread check_for_failed_revive( playerbeingrevived );
  1155.     e_fx = spawn( "script_model", playerbeingrevived.revivetrigger.origin );
  1156.     e_fx setmodel( "tag_origin" );
  1157.     e_fx thread revive_fx_clean_up_on_disconnect( playerbeingrevived );
  1158.     playfxontag( level._effect[ "afterlife_leave" ], e_fx, "tag_origin" );
  1159.     if ( isDefined( playloop ) && playloop )
  1160.     {
  1161.         e_fx playloopsound( "zmb_afterlife_reviving", 0,05 );
  1162.     }
  1163.     while ( self is_reviving_afterlife( playerbeingrevived ) )
  1164.     {
  1165.         wait 0,05;
  1166.         timer += 0,05;
  1167.         if ( self player_is_in_laststand() )
  1168.         {
  1169.             break;
  1170.         }
  1171.         else if ( isDefined( playerbeingrevived.revivetrigger.auto_revive ) && playerbeingrevived.revivetrigger.auto_revive == 1 )
  1172.         {
  1173.             break;
  1174.         }
  1175.         else
  1176.         {
  1177.             if ( timer >= revivetime )
  1178.             {
  1179.                 revived = 1;
  1180.                 break;
  1181.             }
  1182.             else
  1183.             {
  1184.             }
  1185.         }
  1186.     }
  1187.     e_fx delete();
  1188.     if ( isDefined( self.reviveprogressbar ) )
  1189.     {
  1190.         self.reviveprogressbar destroyelem();
  1191.     }
  1192.     if ( isDefined( self.revivetexthud ) )
  1193.     {
  1194.         self.revivetexthud destroy();
  1195.     }
  1196.     if ( isDefined( playerbeingrevived.revivetrigger.auto_revive ) && playerbeingrevived.revivetrigger.auto_revive == 1 )
  1197.     {
  1198.     }
  1199.     else if ( !revived )
  1200.     {
  1201.         if ( isplayer( playerbeingrevived ) )
  1202.         {
  1203.             playerbeingrevived stoprevive( self );
  1204.         }
  1205.     }
  1206.     playerbeingrevived.revivetrigger sethintstring( &"GAME_BUTTON_TO_REVIVE_PLAYER" );
  1207.     playerbeingrevived.revivetrigger.beingrevived = 0;
  1208.     self notify( "do_revive_ended_normally" );
  1209.     self.is_reviving_any--;
  1210.  
  1211.     if ( !revived )
  1212.     {
  1213.         playerbeingrevived thread checkforbleedout( self );
  1214.     }
  1215.     return revived;
  1216. }
  1217.  
  1218. revive_fx_clean_up_on_disconnect( e_corpse )
  1219. {
  1220.     self endon( "death" );
  1221.     e_corpse waittill( "disconnect" );
  1222.     self delete();
  1223. }
  1224.  
  1225. revive_clean_up_on_gameover()
  1226. {
  1227.     self endon( "do_revive_ended_normally" );
  1228.     level waittill( "end_game" );
  1229.     if ( isDefined( self.reviveprogressbar ) )
  1230.     {
  1231.         self.reviveprogressbar destroyelem();
  1232.     }
  1233.     if ( isDefined( self.revivetexthud ) )
  1234.     {
  1235.         self.revivetexthud destroy();
  1236.     }
  1237. }
  1238.  
  1239. is_reviving_afterlife( revivee )
  1240. {
  1241.     if ( self usebuttonpressed() )
  1242.     {
  1243.         return afterlife_can_revive( revivee );
  1244.     }
  1245. }
  1246.  
  1247. afterlife_save_loadout()
  1248. {
  1249.     primaries = self getweaponslistprimaries();
  1250.     currentweapon = self getcurrentweapon();
  1251.     self.loadout = spawnstruct();
  1252.     self.loadout.player = self;
  1253.     self.loadout.weapons = [];
  1254.     self.loadout.score = self.score;
  1255.     self.loadout.current_weapon = 0;
  1256.     _a1516 = primaries;
  1257.     index = getFirstArrayKey( _a1516 );
  1258.     while ( isDefined( index ) )
  1259.     {
  1260.         weapon = _a1516[ index ];
  1261.         self.loadout.weapons[ index ] = weapon;
  1262.         self.loadout.stockcount[ index ] = self getweaponammostock( weapon );
  1263.         self.loadout.clipcount[ index ] = self getweaponammoclip( weapon );
  1264.         if ( weaponisdualwield( weapon ) )
  1265.         {
  1266.             weapon_dw = weapondualwieldweaponname( weapon );
  1267.             self.loadout.clipcount2[ index ] = self getweaponammoclip( weapon_dw );
  1268.         }
  1269.         weapon_alt = weaponaltweaponname( weapon );
  1270.         if ( weapon_alt != "none" )
  1271.         {
  1272.             self.loadout.stockcountalt[ index ] = self getweaponammostock( weapon_alt );
  1273.             self.loadout.clipcountalt[ index ] = self getweaponammoclip( weapon_alt );
  1274.         }
  1275.         if ( weapon == currentweapon )
  1276.         {
  1277.             self.loadout.current_weapon = index;
  1278.         }
  1279.         index = getNextArrayKey( _a1516, index );
  1280.     }
  1281.     self.loadout.equipment = self get_player_equipment();
  1282.     if ( isDefined( self.loadout.equipment ) )
  1283.     {
  1284.         self equipment_take( self.loadout.equipment );
  1285.     }
  1286.     if ( self hasweapon( "claymore_zm" ) )
  1287.     {
  1288.         self.loadout.hasclaymore = 1;
  1289.         self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" );
  1290.     }
  1291.     if ( self hasweapon( "emp_grenade_zm" ) )
  1292.     {
  1293.         self.loadout.hasemp = 1;
  1294.         self.loadout.empclip = self getweaponammoclip( "emp_grenade_zm" );
  1295.     }
  1296.     if ( self hasweapon( "bouncing_tomahawk_zm" ) || self hasweapon( "upgraded_tomahawk_zm" ) )
  1297.     {
  1298.         self.loadout.hastomahawk = 1;
  1299.         self setclientfieldtoplayer( "tomahawk_in_use", 0 );
  1300.     }
  1301.     self.loadout.perks = afterlife_save_perks( self );
  1302.     lethal_grenade = self get_player_lethal_grenade();
  1303.     if ( self hasweapon( lethal_grenade ) )
  1304.     {
  1305.         self.loadout.grenade = self getweaponammoclip( lethal_grenade );
  1306.     }
  1307.     else
  1308.     {
  1309.         self.loadout.grenade = 0;
  1310.     }
  1311.     self.loadout.lethal_grenade = lethal_grenade;
  1312.     self set_player_lethal_grenade( undefined );
  1313. }
  1314.  
  1315. afterlife_give_loadout()
  1316. {
  1317.     self takeallweapons();
  1318.     loadout = self.loadout;
  1319.     primaries = self getweaponslistprimaries();
  1320.     while ( loadout.weapons.size > 1 || primaries.size > 1 )
  1321.     {
  1322.         _a1601 = primaries;
  1323.         _k1601 = getFirstArrayKey( _a1601 );
  1324.         while ( isDefined( _k1601 ) )
  1325.         {
  1326.             weapon = _a1601[ _k1601 ];
  1327.             self takeweapon( weapon );
  1328.             _k1601 = getNextArrayKey( _a1601, _k1601 );
  1329.         }
  1330.     }
  1331.     i = 0;
  1332.     while ( i < loadout.weapons.size )
  1333.     {
  1334.         if ( !isDefined( loadout.weapons[ i ] ) )
  1335.         {
  1336.             i++;
  1337.             continue;
  1338.         }
  1339.         else if ( loadout.weapons[ i ] == "none" )
  1340.         {
  1341.             i++;
  1342.             continue;
  1343.         }
  1344.         else
  1345.         {
  1346.             weapon = loadout.weapons[ i ];
  1347.             stock_amount = loadout.stockcount[ i ];
  1348.             clip_amount = loadout.clipcount[ i ];
  1349.             if ( !self hasweapon( weapon ) )
  1350.             {
  1351.                 self giveweapon( weapon, 0, self maps/mp/zombies/_zm_weapons::get_pack_a_punch_weapon_options( weapon ) );
  1352.                 self setweaponammostock( weapon, stock_amount );
  1353.                 self setweaponammoclip( weapon, clip_amount );
  1354.                 if ( weaponisdualwield( weapon ) )
  1355.                 {
  1356.                     weapon_dw = weapondualwieldweaponname( weapon );
  1357.                     self setweaponammoclip( weapon_dw, loadout.clipcount2[ i ] );
  1358.                 }
  1359.                 weapon_alt = weaponaltweaponname( weapon );
  1360.                 if ( weapon_alt != "none" )
  1361.                 {
  1362.                     self setweaponammostock( weapon_alt, loadout.stockcountalt[ i ] );
  1363.                     self setweaponammoclip( weapon_alt, loadout.clipcountalt[ i ] );
  1364.                 }
  1365.             }
  1366.         }
  1367.         i++;
  1368.     }
  1369.     self setspawnweapon( loadout.weapons[ loadout.current_weapon ] );
  1370.     self switchtoweaponimmediate( loadout.weapons[ loadout.current_weapon ] );
  1371.     if ( isDefined( self get_player_melee_weapon() ) )
  1372.     {
  1373.         self giveweapon( self get_player_melee_weapon() );
  1374.     }
  1375.     self maps/mp/zombies/_zm_equipment::equipment_give( self.loadout.equipment );
  1376.     if ( isDefined( loadout.hasclaymore ) && loadout.hasclaymore && !self hasweapon( "claymore_zm" ) )
  1377.     {
  1378.         self giveweapon( "claymore_zm" );
  1379.         self set_player_placeable_mine( "claymore_zm" );
  1380.         self setactionslot( 4, "weapon", "claymore_zm" );
  1381.         self setweaponammoclip( "claymore_zm", loadout.claymoreclip );
  1382.     }
  1383.     if ( isDefined( loadout.hasemp ) && loadout.hasemp )
  1384.     {
  1385.         self giveweapon( "emp_grenade_zm" );
  1386.         self setweaponammoclip( "emp_grenade_zm", loadout.empclip );
  1387.     }
  1388.     if ( isDefined( loadout.hastomahawk ) && loadout.hastomahawk )
  1389.     {
  1390.         self giveweapon( self.current_tomahawk_weapon );
  1391.         self set_player_tactical_grenade( self.current_tomahawk_weapon );
  1392.         self setclientfieldtoplayer( "tomahawk_in_use", 1 );
  1393.     }
  1394.     self.score = loadout.score;
  1395.     perk_array = maps/mp/zombies/_zm_perks::get_perk_array( 1 );
  1396.     i = 0;
  1397.     while ( i < perk_array.size )
  1398.     {
  1399.         perk = perk_array[ i ];
  1400.         self unsetperk( perk );
  1401.         self set_perk_clientfield( perk, 0 );
  1402.         i++;
  1403.     }
  1404.     while ( isDefined( self.keep_perks ) && self.keep_perks && isDefined( loadout.perks ) && loadout.perks.size > 0 )
  1405.     {
  1406.         i = 0;
  1407.         while ( i < loadout.perks.size )
  1408.         {
  1409.             if ( self hasperk( loadout.perks[ i ] ) )
  1410.             {
  1411.                 i++;
  1412.                 continue;
  1413.             }
  1414.             else if ( loadout.perks[ i ] == "specialty_quickrevive" && flag( "solo_game" ) )
  1415.             {
  1416.                 level.solo_game_free_player_quickrevive = 1;
  1417.             }
  1418.             if ( loadout.perks[ i ] == "specialty_finalstand" )
  1419.             {
  1420.                 i++;
  1421.                 continue;
  1422.             }
  1423.             else
  1424.             {
  1425.                 maps/mp/zombies/_zm_perks::give_perk( loadout.perks[ i ] );
  1426.             }
  1427.             i++;
  1428.         }
  1429.     }
  1430.     self.keep_perks = undefined;
  1431.     self set_player_lethal_grenade( self.loadout.lethal_grenade );
  1432.     if ( loadout.grenade > 0 )
  1433.     {
  1434.         curgrenadecount = 0;
  1435.         if ( self hasweapon( self get_player_lethal_grenade() ) )
  1436.         {
  1437.             self getweaponammoclip( self get_player_lethal_grenade() );
  1438.         }
  1439.         else
  1440.         {
  1441.             self giveweapon( self get_player_lethal_grenade() );
  1442.         }
  1443.         self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount );
  1444.     }
  1445. }
  1446.  
  1447. afterlife_fake_death()
  1448. {
  1449.     level notify( "fake_death" );
  1450.     self notify( "fake_death" );
  1451.     self takeallweapons();
  1452.     self allowstand( 0 );
  1453.     self allowcrouch( 0 );
  1454.     self allowprone( 1 );
  1455.     self setstance( "prone" );
  1456.     while ( self is_jumping() )
  1457.     {
  1458.         while ( self is_jumping() )
  1459.         {
  1460.             wait 0,05;
  1461.         }
  1462.     }
  1463.     playfx( level._effect[ "afterlife_enter" ], self.origin );
  1464.     self.ignoreme = 1;
  1465.     self enableinvulnerability();
  1466.     self freezecontrols( 1 );
  1467. }
  1468.  
  1469. afterlife_fake_revive()
  1470. {
  1471.     level notify( "fake_revive" );
  1472.     self notify( "fake_revive" );
  1473.     playsoundatposition( "zmb_afterlife_spawn_leave", self.origin );
  1474.     if ( flag( "afterlife_start_over" ) )
  1475.     {
  1476.         spawnpoint = [[ level.afterlife_get_spawnpoint ]]();
  1477.         trace_start = spawnpoint.origin;
  1478.         trace_end = spawnpoint.origin + vectorScale( ( 0, 0, 1 ), 200 );
  1479.         respawn_trace = playerphysicstrace( trace_start, trace_end );
  1480.         self setorigin( respawn_trace );
  1481.         self setplayerangles( spawnpoint.angles );
  1482.         playsoundatposition( "zmb_afterlife_spawn_enter", spawnpoint.origin );
  1483.     }
  1484.     else
  1485.     {
  1486.         playsoundatposition( "zmb_afterlife_spawn_enter", self.origin );
  1487.     }
  1488.     self allowstand( 1 );
  1489.     self allowcrouch( 0 );
  1490.     self allowprone( 0 );
  1491.     self.ignoreme = 0;
  1492.     self setstance( "stand" );
  1493.     self giveweapon( "lightning_hands_zm" );
  1494.     self switchtoweapon( "lightning_hands_zm" );
  1495.     self.score = 0;
  1496.     wait 1;
  1497. }
  1498.  
  1499. afterlife_get_spawnpoint()
  1500. {
  1501.     spawnpoint = check_for_valid_spawn_in_zone( self );
  1502.     if ( !isDefined( spawnpoint ) )
  1503.     {
  1504.         spawnpoint = maps/mp/zombies/_zm::check_for_valid_spawn_near_position( self, self.origin, 1 );
  1505.     }
  1506.     if ( !isDefined( spawnpoint ) )
  1507.     {
  1508.         spawnpoint = maps/mp/zombies/_zm::check_for_valid_spawn_near_team( self, 1 );
  1509.     }
  1510.     if ( !isDefined( spawnpoint ) )
  1511.     {
  1512.         match_string = "";
  1513.         location = level.scr_zm_map_start_location;
  1514.         if ( location != "default" && location == "" && isDefined( level.default_start_location ) )
  1515.         {
  1516.             location = level.default_start_location;
  1517.         }
  1518.         match_string = ( level.scr_zm_ui_gametype + "_" ) + location;
  1519.         spawnpoints = [];
  1520.         structs = getstructarray( "initial_spawn", "script_noteworthy" );
  1521.         while ( isDefined( structs ) )
  1522.         {
  1523.             _a1858 = structs;
  1524.             _k1858 = getFirstArrayKey( _a1858 );
  1525.             while ( isDefined( _k1858 ) )
  1526.             {
  1527.                 struct = _a1858[ _k1858 ];
  1528.                 while ( isDefined( struct.script_string ) )
  1529.                 {
  1530.                     tokens = strtok( struct.script_string, " " );
  1531.                     _a1864 = tokens;
  1532.                     _k1864 = getFirstArrayKey( _a1864 );
  1533.                     while ( isDefined( _k1864 ) )
  1534.                     {
  1535.                         token = _a1864[ _k1864 ];
  1536.                         if ( token == match_string )
  1537.                         {
  1538.                             spawnpoints[ spawnpoints.size ] = struct;
  1539.                         }
  1540.                         _k1864 = getNextArrayKey( _a1864, _k1864 );
  1541.                     }
  1542.                 }
  1543.                 _k1858 = getNextArrayKey( _a1858, _k1858 );
  1544.             }
  1545.         }
  1546.         if ( !isDefined( spawnpoints ) || spawnpoints.size == 0 )
  1547.         {
  1548.             spawnpoints = getstructarray( "initial_spawn_points", "targetname" );
  1549.         }
  1550. /#
  1551.         assert( isDefined( spawnpoints ), "Could not find initial spawn points!" );
  1552. #/
  1553.         spawnpoint = maps/mp/zombies/_zm::getfreespawnpoint( spawnpoints, self );
  1554.     }
  1555.     return spawnpoint;
  1556. }
  1557.  
  1558. check_for_valid_spawn_in_zone( player )
  1559. {
  1560.     a_spawn_points = maps/mp/gametypes_zm/_zm_gametype::get_player_spawns_for_gametype();
  1561.     if ( isDefined( level.e_gondola ) && isDefined( level.e_gondola.is_moving ) && level.e_gondola.is_moving )
  1562.     {
  1563.         if ( player maps/mp/zm_alcatraz_travel::is_player_on_gondola() )
  1564.         {
  1565.             if ( level.e_gondola.destination == "roof" )
  1566.             {
  1567.                 str_player_zone = "zone_cellblock_west_gondola";
  1568.             }
  1569.             else
  1570.             {
  1571.                 if ( level.e_gondola.destination == "docks" )
  1572.                 {
  1573.                     str_player_zone = "zone_dock";
  1574.                 }
  1575.             }
  1576.         }
  1577.         else
  1578.         {
  1579.             str_player_zone = player maps/mp/zombies/_zm_zonemgr::get_player_zone();
  1580.         }
  1581.     }
  1582.     else
  1583.     {
  1584.         str_player_zone = player maps/mp/zombies/_zm_zonemgr::get_player_zone();
  1585.     }
  1586. /#
  1587.     println( "The player is not in a zone at origin " + player.origin );
  1588. #/
  1589.     _a1929 = a_spawn_points;
  1590.     _k1929 = getFirstArrayKey( _a1929 );
  1591.     while ( isDefined( _k1929 ) )
  1592.     {
  1593.         spawn_point = _a1929[ _k1929 ];
  1594.         while ( spawn_point.script_noteworthy == str_player_zone )
  1595.         {
  1596.             a_spawn_structs = getstructarray( spawn_point.target, "targetname" );
  1597.             a_spawn_structs = get_array_of_closest( player.origin, a_spawn_structs );
  1598.             _a1939 = a_spawn_structs;
  1599.             _k1939 = getFirstArrayKey( _a1939 );
  1600.             while ( isDefined( _k1939 ) )
  1601.             {
  1602.                 s_spawn = _a1939[ _k1939 ];
  1603.                 if ( !flag( "afterlife_start_over" ) )
  1604.                 {
  1605.                     if ( isDefined( s_spawn.en_num ) && s_spawn.en_num != player.playernum )
  1606.                     {
  1607.                     }
  1608.                 }
  1609.                 else
  1610.                 {
  1611.                     if ( positionwouldtelefrag( s_spawn.origin ) || distancesquared( player.origin, s_spawn.origin ) < 250000 )
  1612.                     {
  1613.                         break;
  1614.                     }
  1615.                     else return s_spawn;
  1616.                 }
  1617.                 _k1939 = getNextArrayKey( _a1939, _k1939 );
  1618.             }
  1619.             a_spawn_structs = get_array_of_farthest( player.origin, a_spawn_structs, undefined, 250000 );
  1620.             _a1962 = a_spawn_structs;
  1621.             _k1962 = getFirstArrayKey( _a1962 );
  1622.             while ( isDefined( _k1962 ) )
  1623.             {
  1624.                 s_spawn = _a1962[ _k1962 ];
  1625.                 if ( positionwouldtelefrag( s_spawn.origin ) )
  1626.                 {
  1627.                 }
  1628.                 else return s_spawn;
  1629.                 _k1962 = getNextArrayKey( _a1962, _k1962 );
  1630.             }
  1631.         }
  1632.         _k1929 = getNextArrayKey( _a1929, _k1929 );
  1633.     }
  1634.     return undefined;
  1635. }
  1636.  
  1637. afterlife_save_perks( ent )
  1638. {
  1639.     perk_array = ent get_perk_array( 1 );
  1640.     _a1989 = perk_array;
  1641.     _k1989 = getFirstArrayKey( _a1989 );
  1642.     while ( isDefined( _k1989 ) )
  1643.     {
  1644.         perk = _a1989[ _k1989 ];
  1645.         ent unsetperk( perk );
  1646.         _k1989 = getNextArrayKey( _a1989, _k1989 );
  1647.     }
  1648.     return perk_array;
  1649. }
  1650.  
  1651. afterlife_hostmigration()
  1652. {
  1653.     while ( 1 )
  1654.     {
  1655.         level waittill( "host_migration_end" );
  1656.         _a2007 = getplayers();
  1657.         _k2007 = getFirstArrayKey( _a2007 );
  1658.         while ( isDefined( _k2007 ) )
  1659.         {
  1660.             player = _a2007[ _k2007 ];
  1661.             player setclientfieldtoplayer( "player_lives", player.lives );
  1662.             if ( isDefined( player.e_afterlife_corpse ) )
  1663.             {
  1664.                 player.e_afterlife_corpse setclientfield( "player_corpse_id", 0 );
  1665.             }
  1666.             _k2007 = getNextArrayKey( _a2007, _k2007 );
  1667.         }
  1668.         wait_network_frame();
  1669.         wait_network_frame();
  1670.         _a2021 = getplayers();
  1671.         _k2021 = getFirstArrayKey( _a2021 );
  1672.         while ( isDefined( _k2021 ) )
  1673.         {
  1674.             player = _a2021[ _k2021 ];
  1675.             if ( isDefined( player.e_afterlife_corpse ) )
  1676.             {
  1677.                 player.e_afterlife_corpse setclientfield( "player_corpse_id", player getentitynumber() + 1 );
  1678.             }
  1679.             _k2021 = getNextArrayKey( _a2021, _k2021 );
  1680.         }
  1681.     }
  1682. }
  1683.  
  1684. afterlife_reduce_mana( n_mana )
  1685. {
  1686.     if ( isDefined( self.afterlife ) && !self.afterlife )
  1687.     {
  1688.         return;
  1689.     }
  1690.     if ( isDefined( level.hostmigrationtimer ) )
  1691.     {
  1692.         return;
  1693.     }
  1694.     if ( isDefined( self.infinite_mana ) && self.infinite_mana )
  1695.     {
  1696.         self.manacur = 200;
  1697.         return;
  1698.     }
  1699. /#
  1700.     if ( getDvarInt( "zombie_cheat" ) >= 1 )
  1701.     {
  1702.         self.manacur = 200;
  1703.         return;
  1704. #/
  1705.     }
  1706.     if ( isDefined( self.e_afterlife_corpse ) && isDefined( self.e_afterlife_corpse.revivetrigger.beingrevived ) && self.e_afterlife_corpse.revivetrigger.beingrevived )
  1707.     {
  1708.         return;
  1709.     }
  1710.     self.manacur -= n_mana;
  1711. }
  1712.  
  1713. afterlife_lightning_watch( corpse )
  1714. {
  1715.     self endon( "disconnect" );
  1716.     corpse endon( "player_revived" );
  1717.     while ( 1 )
  1718.     {
  1719.         self waittill( "weapon_fired" );
  1720.         self afterlife_reduce_mana( 1 );
  1721.         wait 0,05;
  1722.     }
  1723. }
  1724.  
  1725. afterlife_jump_watch( corpse )
  1726. {
  1727.     self endon( "disconnect" );
  1728.     corpse endon( "player_revived" );
  1729.     while ( 1 )
  1730.     {
  1731.         if ( self is_jumping() )
  1732.         {
  1733.             self afterlife_reduce_mana( 0,3 );
  1734.             earthquake( 0,1, 0,05, self.origin, 200, self );
  1735.         }
  1736.         wait 0,05;
  1737.     }
  1738. }
  1739.  
  1740. afterlife_trigger_create( s_origin )
  1741. {
  1742.     s_origin.unitrigger_stub = spawnstruct();
  1743.     s_origin.unitrigger_stub.origin = s_origin.origin;
  1744.     s_origin.unitrigger_stub.radius = 36;
  1745.     s_origin.unitrigger_stub.height = 256;
  1746.     s_origin.unitrigger_stub.script_unitrigger_type = "unitrigger_radius_use";
  1747.     s_origin.unitrigger_stub.hint_string = &"ZM_PRISON_AFTERLIFE_KILL";
  1748.     s_origin.unitrigger_stub.cursor_hint = "HINT_NOICON";
  1749.     s_origin.unitrigger_stub.require_look_at = 1;
  1750.     s_origin.unitrigger_stub.prompt_and_visibility_func = ::afterlife_trigger_visibility;
  1751.     maps/mp/zombies/_zm_unitrigger::unitrigger_force_per_player_triggers( s_origin.unitrigger_stub, 1 );
  1752.     maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( s_origin.unitrigger_stub, ::afterlife_trigger_think );
  1753. }
  1754.  
  1755. reset_all_afterlife_unitriggers()
  1756. {
  1757.     a_afterlife_triggers = getstructarray( "afterlife_trigger", "targetname" );
  1758.     _a2129 = a_afterlife_triggers;
  1759.     _k2129 = getFirstArrayKey( _a2129 );
  1760.     while ( isDefined( _k2129 ) )
  1761.     {
  1762.         struct = _a2129[ _k2129 ];
  1763.         maps/mp/zombies/_zm_unitrigger::unregister_unitrigger( struct.unitrigger_stub );
  1764.         maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( struct.unitrigger_stub, ::afterlife_trigger_think );
  1765.         _k2129 = getNextArrayKey( _a2129, _k2129 );
  1766.     }
  1767. }
  1768.  
  1769. afterlife_trigger_visibility( player )
  1770. {
  1771.     b_is_invis = player.afterlife;
  1772.     self setinvisibletoplayer( player, b_is_invis );
  1773.     if ( player.lives == 0 )
  1774.     {
  1775.         self sethintstring( &"ZM_PRISON_OUT_OF_LIVES" );
  1776.     }
  1777.     else
  1778.     {
  1779.         self sethintstring( self.stub.hint_string );
  1780.         if ( !isDefined( player.has_played_afterlife_trigger_hint ) && player is_player_looking_at( self.stub.origin, 0,25 ) )
  1781.         {
  1782.             if ( isDefined( player.dontspeak ) && !player.dontspeak )
  1783.             {
  1784.                 player thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "killswitch_clue" );
  1785.                 player.has_played_afterlife_trigger_hint = 1;
  1786.             }
  1787.         }
  1788.     }
  1789.     return !b_is_invis;
  1790. }
  1791.  
  1792. afterlife_trigger_think()
  1793. {
  1794.     self endon( "kill_trigger" );
  1795.     flag_wait( "start_zombie_round_logic" );
  1796.     while ( 1 )
  1797.     {
  1798.         self waittill( "trigger", player );
  1799.         while ( player.lives <= 0 )
  1800.         {
  1801.             self playsound( "zmb_no_cha_ching" );
  1802.         }
  1803.         while ( player is_reviving_any() || player player_is_in_laststand() )
  1804.         {
  1805.             wait 0,1;
  1806.         }
  1807.         if ( isDefined( player.afterlife ) && !player.afterlife )
  1808.         {
  1809.             self setinvisibletoplayer( player, 1 );
  1810.             self playsound( "zmb_afterlife_trigger_activate" );
  1811.             player playsoundtoplayer( "zmb_afterlife_trigger_electrocute", player );
  1812.             player thread afterlife_trigger_used_vo();
  1813.             self sethintstring( "" );
  1814.             player.keep_perks = 1;
  1815.             player afterlife_remove();
  1816.             player.afterlife = 1;
  1817.             player thread afterlife_laststand();
  1818.             e_fx = spawn( "script_model", self.origin );
  1819.             e_fx setmodel( "tag_origin" );
  1820.             e_fx.angles = vectorScale( ( 0, 0, 1 ), 90 );
  1821.             playfxontag( level._effect[ "afterlife_kill_point_fx" ], e_fx, "tag_origin" );
  1822.             wait 2;
  1823.             e_fx delete();
  1824.             self sethintstring( &"ZM_PRISON_AFTERLIFE_KILL" );
  1825.         }
  1826.     }
  1827. }
  1828.  
  1829. afterlife_interact_object_think()
  1830. {
  1831.     self endon( "afterlife_interact_complete" );
  1832.     if ( isDefined( self.script_int ) && self.script_int > 0 )
  1833.     {
  1834.         n_total_interact_count = self.script_int;
  1835.     }
  1836.     else
  1837.     {
  1838.         if ( !isDefined( self.script_int ) || isDefined( self.script_int ) && self.script_int <= 0 )
  1839.         {
  1840.             n_total_interact_count = 0;
  1841.         }
  1842.     }
  1843.     n_count = 0;
  1844.     self.health = 5000;
  1845.     self setcandamage( 1 );
  1846.     self useanimtree( -1 );
  1847.     self playloopsound( "zmb_afterlife_shockbox_off", 1 );
  1848.     if ( !isDefined( level.shockbox_anim ) )
  1849.     {
  1850.         level.shockbox_anim[ "on" ] = %fxanim_zom_al_shock_box_on_anim;
  1851.         level.shockbox_anim[ "off" ] = %fxanim_zom_al_shock_box_off_anim;
  1852.     }
  1853.     trig_spawn_offset = ( 0, 0, 1 );
  1854.     if ( self.model != "p6_anim_zm_al_nixie_tubes" )
  1855.     {
  1856.         if ( isDefined( self.script_string ) && self.script_string == "intro_powerup_activate" )
  1857.         {
  1858.             self.t_bump = spawn( "trigger_radius", self.origin + vectorScale( ( 0, 0, 1 ), 28 ), 0, 28, 64 );
  1859.         }
  1860.         else
  1861.         {
  1862.             if ( issubstr( self.model, "p6_zm_al_shock_box" ) )
  1863.             {
  1864.                 trig_spawn_offset = ( 0, 11, 46 );
  1865.                 str_hint = &"ZM_PRISON_AFTERLIFE_INTERACT";
  1866.             }
  1867.             else
  1868.             {
  1869.                 if ( issubstr( self.model, "p6_zm_al_power_station_panels" ) )
  1870.                 {
  1871.                     trig_spawn_offset = ( 32, 35, 58 );
  1872.                     str_hint = &"ZM_PRISON_AFTERLIFE_OVERLOAD";
  1873.                 }
  1874.             }
  1875.             afterlife_interact_hint_trigger_create( self, trig_spawn_offset, str_hint );
  1876.         }
  1877.     }
  1878.     while ( 1 )
  1879.     {
  1880.         if ( isDefined( self.unitrigger_stub ) )
  1881.         {
  1882.             self.unitrigger_stub.is_activated_in_afterlife = 0;
  1883.         }
  1884.         else
  1885.         {
  1886.             if ( isDefined( self.t_bump ) )
  1887.             {
  1888.                 self.t_bump setcursorhint( "HINT_NOICON" );
  1889.                 self.t_bump sethintstring( &"ZM_PRISON_AFTERLIFE_INTERACT" );
  1890.             }
  1891.         }
  1892.         self waittill( "damage", amount, attacker );
  1893.         if ( attacker == level || isplayer( attacker ) && attacker getcurrentweapon() == "lightning_hands_zm" )
  1894.         {
  1895.             if ( isDefined( self.script_string ) )
  1896.             {
  1897.                 if ( isDefined( level.afterlife_interact_dist ) )
  1898.                 {
  1899.                     if ( attacker == level || distancesquared( attacker.origin, self.origin ) < ( level.afterlife_interact_dist * level.afterlife_interact_dist ) )
  1900.                     {
  1901.                         level notify( self.script_string );
  1902.                         if ( isDefined( self.unitrigger_stub ) )
  1903.                         {
  1904.                             self.unitrigger_stub.is_activated_in_afterlife = 1;
  1905.                             self.unitrigger_stub maps/mp/zombies/_zm_unitrigger::run_visibility_function_for_all_triggers();
  1906.                         }
  1907.                         else
  1908.                         {
  1909.                             if ( isDefined( self.t_bump ) )
  1910.                             {
  1911.                                 self.t_bump sethintstring( "" );
  1912.                             }
  1913.                         }
  1914.                         self playloopsound( "zmb_afterlife_shockbox_on", 1 );
  1915.                         if ( self.model == "p6_zm_al_shock_box_off" )
  1916.                         {
  1917.                             if ( !isDefined( self.playing_fx ) )
  1918.                             {
  1919.                                 playfxontag( level._effect[ "box_activated" ], self, "tag_origin" );
  1920.                                 self.playing_fx = 1;
  1921.                                 self thread afterlife_interact_object_fx_cooldown();
  1922.                                 self playsound( "zmb_powerpanel_activate" );
  1923.                             }
  1924.                             self setmodel( "p6_zm_al_shock_box_on" );
  1925.                             self setanim( level.shockbox_anim[ "on" ] );
  1926.                         }
  1927.                         n_count++;
  1928.                         if ( n_total_interact_count <= 0 || n_count < n_total_interact_count )
  1929.                         {
  1930.                             self waittill( "afterlife_interact_reset" );
  1931.                             self playloopsound( "zmb_afterlife_shockbox_off", 1 );
  1932.                             if ( self.model == "p6_zm_al_shock_box_on" )
  1933.                             {
  1934.                                 self setmodel( "p6_zm_al_shock_box_off" );
  1935.                                 self setanim( level.shockbox_anim[ "off" ] );
  1936.                             }
  1937.                             if ( isDefined( self.unitrigger_stub ) )
  1938.                             {
  1939.                                 self.unitrigger_stub.is_activated_in_afterlife = 0;
  1940.                                 self.unitrigger_stub maps/mp/zombies/_zm_unitrigger::run_visibility_function_for_all_triggers();
  1941.                             }
  1942.                             break;
  1943.                         }
  1944.                         else
  1945.                         {
  1946.                             if ( isDefined( self.t_bump ) )
  1947.                             {
  1948.                                 self.t_bump delete();
  1949.                             }
  1950.                             return;
  1951.                         }
  1952.                     }
  1953.                 }
  1954.             }
  1955.         }
  1956.         else
  1957.         {
  1958.         }
  1959.     }
  1960. }
  1961.  
  1962. afterlife_interact_hint_trigger_create( m_interact, v_trig_offset, str_hint )
  1963. {
  1964.     m_interact.unitrigger_stub = spawnstruct();
  1965.     m_interact.unitrigger_stub.origin = ( ( m_interact.origin + ( anglesToForward( m_interact.angles ) * v_trig_offset[ 0 ] ) ) + ( anglesToRight( m_interact.angles ) * v_trig_offset[ 1 ] ) ) + ( anglesToUp( m_interact.angles ) * v_trig_offset[ 2 ] );
  1966.     m_interact.unitrigger_stub.radius = 40;
  1967.     m_interact.unitrigger_stub.height = 64;
  1968.     m_interact.unitrigger_stub.script_unitrigger_type = "unitrigger_radius_use";
  1969.     m_interact.unitrigger_stub.hint_string = str_hint;
  1970.     m_interact.unitrigger_stub.cursor_hint = "HINT_NOICON";
  1971.     m_interact.unitrigger_stub.require_look_at = 1;
  1972.     m_interact.unitrigger_stub.ignore_player_valid = 1;
  1973.     m_interact.unitrigger_stub.prompt_and_visibility_func = ::afterlife_trigger_visible_in_afterlife;
  1974.     maps/mp/zombies/_zm_unitrigger::register_static_unitrigger( m_interact.unitrigger_stub, ::afterlife_interact_hint_trigger_think );
  1975. }
  1976.  
  1977. afterlife_trigger_visible_in_afterlife( player )
  1978. {
  1979.     if ( isDefined( self.stub.is_activated_in_afterlife ) )
  1980.     {
  1981.         b_is_invis = self.stub.is_activated_in_afterlife;
  1982.     }
  1983.     self setinvisibletoplayer( player, b_is_invis );
  1984.     self sethintstring( self.stub.hint_string );
  1985.     if ( !b_is_invis )
  1986.     {
  1987.         if ( player is_player_looking_at( self.origin, 0,25 ) )
  1988.         {
  1989.             if ( cointoss() )
  1990.             {
  1991.                 player thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "need_electricity" );
  1992.             }
  1993.             else
  1994.             {
  1995.                 player thread maps/mp/zombies/_zm_audio::create_and_play_dialog( "general", "electric_zap" );
  1996.             }
  1997.         }
  1998.     }
  1999.     return !b_is_invis;
  2000. }
  2001.  
  2002. afterlife_interact_hint_trigger_think()
  2003. {
  2004.     self endon( "kill_trigger" );
  2005.     while ( 1 )
  2006.     {
  2007.         self waittill( "trigger" );
  2008.         wait 1000;
  2009.     }
  2010. }
  2011.  
  2012. afterlife_interact_object_fx_cooldown()
  2013. {
  2014.     wait 2;
  2015.     self.playing_fx = undefined;
  2016. }
  2017.  
  2018. afterlife_zombie_damage()
  2019. {
  2020.     self.actor_damage_func = ::afterlife_damage_func;
  2021. }
  2022.  
  2023. afterlife_damage_func( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime )
  2024. {
  2025.     if ( sweapon == "lightning_hands_zm" )
  2026.     {
  2027.         while ( !isDefined( self.zapped ) )
  2028.         {
  2029.             a_zombies = get_array_of_closest( self.origin, getaiarray( "axis" ), undefined, 5, 80 );
  2030.             i = 0;
  2031.             while ( i < a_zombies.size )
  2032.             {
  2033.                 if ( isalive( a_zombies[ i ] ) && !isDefined( a_zombies[ i ].zapped ) )
  2034.                 {
  2035.                     a_zombies[ i ] notify( "zapped" );
  2036.                     a_zombies[ i ] thread [[ level.afterlife_zapped ]]();
  2037.                     wait 0,05;
  2038.                 }
  2039.                 i++;
  2040.             }
  2041.         }
  2042.         return 0;
  2043.     }
  2044.     return idamage;
  2045. }
  2046.  
  2047. afterlife_zapped()
  2048. {
  2049.     self endon( "death" );
  2050.     self endon( "zapped" );
  2051.     if ( self.ai_state == "find_flesh" )
  2052.     {
  2053.         self.zapped = 1;
  2054.         n_ideal_dist_sq = 490000;
  2055.         n_min_dist_sq = 10000;
  2056.         a_nodes = getanynodearray( self.origin, 1200 );
  2057.         a_nodes = arraycombine( a_nodes, getanynodearray( self.origin + vectorScale( ( 0, 0, 1 ), 120 ), 1200 ), 0, 0 );
  2058.         a_nodes = arraycombine( a_nodes, getanynodearray( self.origin - vectorScale( ( 0, 0, 1 ), 120 ), 1200 ), 0, 0 );
  2059.         a_nodes = array_randomize( a_nodes );
  2060.         nd_target = undefined;
  2061.         i = 0;
  2062.         while ( i < a_nodes.size )
  2063.         {
  2064.             if ( distance2dsquared( a_nodes[ i ].origin, self.origin ) > n_ideal_dist_sq )
  2065.             {
  2066.                 if ( a_nodes[ i ] is_valid_teleport_node() )
  2067.                 {
  2068.                     nd_target = a_nodes[ i ];
  2069.                     break;
  2070.                 }
  2071.             }
  2072.             else
  2073.             {
  2074.                 i++;
  2075.             }
  2076.         }
  2077.         while ( !isDefined( nd_target ) )
  2078.         {
  2079.             i = 0;
  2080.             while ( i < a_nodes.size )
  2081.             {
  2082.                 if ( distance2dsquared( a_nodes[ i ].origin, self.origin ) > n_min_dist_sq )
  2083.                 {
  2084.                     if ( a_nodes[ i ] is_valid_teleport_node() )
  2085.                     {
  2086.                         nd_target = a_nodes[ i ];
  2087.                         break;
  2088.                     }
  2089.                 }
  2090.                 else
  2091.                 {
  2092.                     i++;
  2093.                 }
  2094.             }
  2095.         }
  2096.         if ( isDefined( nd_target ) )
  2097.         {
  2098.             v_fx_offset = vectorScale( ( 0, 0, 1 ), 40 );
  2099.             playfx( level._effect[ "afterlife_teleport" ], self.origin );
  2100.             playsoundatposition( "zmb_afterlife_zombie_warp_out", self.origin );
  2101.             self hide();
  2102.             linker = spawn( "script_model", self.origin + v_fx_offset );
  2103.             linker setmodel( "tag_origin" );
  2104.             playfxontag( level._effect[ "teleport_ball" ], linker, "tag_origin" );
  2105.             linker thread linker_delete_watch( self );
  2106.             self linkto( linker );
  2107.             linker moveto( nd_target.origin + v_fx_offset, 1 );
  2108.             linker waittill( "movedone" );
  2109.             linker delete();
  2110.             playfx( level._effect[ "afterlife_teleport" ], self.origin );
  2111.             playsoundatposition( "zmb_afterlife_zombie_warp_in", self.origin );
  2112.             self show();
  2113.         }
  2114.         else
  2115.         {
  2116. /#
  2117.             iprintln( "Could not teleport" );
  2118. #/
  2119.             playfx( level._effect[ "afterlife_teleport" ], self.origin );
  2120.             playsoundatposition( "zmb_afterlife_zombie_warp_out", self.origin );
  2121.             level.zombie_total++;
  2122.             self delete();
  2123.             return;
  2124.         }
  2125.         self.zapped = undefined;
  2126.         self.ignoreall = 1;
  2127.         self notify( "stop_find_flesh" );
  2128.         self thread afterlife_zapped_fx();
  2129.         i = 0;
  2130.         while ( i < 3 )
  2131.         {
  2132.             self animscripted( self.origin, self.angles, "zm_afterlife_stun" );
  2133.             self maps/mp/animscripts/shared::donotetracks( "stunned" );
  2134.             i++;
  2135.         }
  2136.         self.ignoreall = 0;
  2137.         self thread maps/mp/zombies/_zm_ai_basic::find_flesh();
  2138.     }
  2139. }
  2140.  
  2141. is_valid_teleport_node()
  2142. {
  2143.     if ( !check_point_in_enabled_zone( self.origin ) )
  2144.     {
  2145.         return 0;
  2146.     }
  2147.     if ( self.type != "Path" )
  2148.     {
  2149.         return 0;
  2150.     }
  2151.     if ( isDefined( self.script_noteworthy ) && self.script_noteworthy == "no_teleport" )
  2152.     {
  2153.         return 0;
  2154.     }
  2155.     if ( isDefined( self.no_teleport ) && self.no_teleport )
  2156.     {
  2157.         return 0;
  2158.     }
  2159.     return 1;
  2160. }
  2161.  
  2162. linker_delete_watch( ai_zombie )
  2163. {
  2164.     self endon( "death" );
  2165.     ai_zombie waittill( "death" );
  2166.     self delete();
  2167. }
  2168.  
  2169. afterlife_zapped_fx()
  2170. {
  2171.     self endon( "death" );
  2172.     playfxontag( level._effect[ "elec_torso" ], self, "J_SpineLower" );
  2173.     self playsound( "zmb_elec_jib_zombie" );
  2174.     wait 1;
  2175.     tagarray = [];
  2176.     tagarray[ 0 ] = "J_Elbow_LE";
  2177.     tagarray[ 1 ] = "J_Elbow_RI";
  2178.     tagarray[ 2 ] = "J_Knee_RI";
  2179.     tagarray[ 3 ] = "J_Knee_LE";
  2180.     tagarray = array_randomize( tagarray );
  2181.     playfxontag( level._effect[ "elec_md" ], self, tagarray[ 0 ] );
  2182.     self playsound( "zmb_elec_jib_zombie" );
  2183.     wait 1;
  2184.     self playsound( "zmb_elec_jib_zombie" );
  2185.     tagarray[ 0 ] = "J_Wrist_RI";
  2186.     tagarray[ 1 ] = "J_Wrist_LE";
  2187.     if ( !isDefined( self.a.gib_ref ) || self.a.gib_ref != "no_legs" )
  2188.     {
  2189.         tagarray[ 2 ] = "J_Ankle_RI";
  2190.         tagarray[ 3 ] = "J_Ankle_LE";
  2191.     }
  2192.     tagarray = array_randomize( tagarray );
  2193.     playfxontag( level._effect[ "elec_sm" ], self, tagarray[ 0 ] );
  2194.     playfxontag( level._effect[ "elec_sm" ], self, tagarray[ 1 ] );
  2195. }
  2196.  
  2197. enable_afterlife_prop()
  2198. {
  2199.     self show();
  2200.     self.script_noteworthy = "afterlife_prop";
  2201.     a_players = getplayers();
  2202.     _a2655 = a_players;
  2203.     _k2655 = getFirstArrayKey( _a2655 );
  2204.     while ( isDefined( _k2655 ) )
  2205.     {
  2206.         player = _a2655[ _k2655 ];
  2207.         if ( isDefined( player.afterlife ) && player.afterlife )
  2208.         {
  2209.             self setvisibletoplayer( player );
  2210.         }
  2211.         else
  2212.         {
  2213.             self setinvisibletoplayer( player );
  2214.         }
  2215.         _k2655 = getNextArrayKey( _a2655, _k2655 );
  2216.     }
  2217. }
  2218.  
  2219. disable_afterlife_prop()
  2220. {
  2221.     self.script_noteworthy = undefined;
  2222.     self setvisibletoall();
  2223. }
  2224.  
  2225. last_stand_conscience_vo()
  2226. {
  2227.     self endon( "player_revived" );
  2228.     self endon( "player_suicide" );
  2229.     self endon( "zombified" );
  2230.     self endon( "disconnect" );
  2231.     self endon( "end_game" );
  2232.     if ( !isDefined( self.conscience_vo_played ) )
  2233.     {
  2234.         self.conscience_vo_played = 0;
  2235.     }
  2236.     self.conscience_vo_played++;
  2237.     convo = [];
  2238.     convo = level.conscience_vo[ "conscience_" + self.character_name + "_convo_" + self.conscience_vo_played ];
  2239.     while ( isDefined( convo ) )
  2240.     {
  2241.         wait 5;
  2242.         a_players = getplayers();
  2243.         while ( a_players.size > 1 )
  2244.         {
  2245.             _a2708 = a_players;
  2246.             _k2708 = getFirstArrayKey( _a2708 );
  2247.             while ( isDefined( _k2708 ) )
  2248.             {
  2249.                 player = _a2708[ _k2708 ];
  2250.                 if ( player != self )
  2251.                 {
  2252.                     if ( distancesquared( self.origin, player.origin ) < 1000000 )
  2253.                     {
  2254.                         return;
  2255.                     }
  2256.                 }
  2257.                 _k2708 = getNextArrayKey( _a2708, _k2708 );
  2258.             }
  2259.         }
  2260.         self.dontspeak = 1;
  2261.         i = 0;
  2262.         while ( i < convo.size )
  2263.         {
  2264.             n_duration = soundgetplaybacktime( convo[ i ] );
  2265.             self playsoundtoplayer( convo[ i ], self );
  2266.             self thread conscience_vo_ended_early( convo[ i ] );
  2267.             wait ( n_duration / 1000 );
  2268.             wait 0,5;
  2269.             i++;
  2270.         }
  2271.     }
  2272.     self.dontspeak = 0;
  2273. }
  2274.  
  2275. conscience_vo_ended_early( str_alias )
  2276. {
  2277.     self notify( "conscience_VO_end_early" );
  2278.     self endon( "conscience_VO_end_early" );
  2279.     self waittill_any( "player_revived", "player_suicide", "zombified", "death", "end_game" );
  2280.     self.dontspeak = 0;
  2281.     self stoplocalsound( str_alias );
  2282. }
  2283.  
  2284. afterlife_trigger_used_vo()
  2285. {
  2286.     a_vo = level.exert_sounds[ self.characterindex + 1 ][ "hitlrg" ];
  2287.     n_index = randomint( a_vo.size );
  2288.     self playsound( a_vo[ n_index ] );
  2289. }
Advertisement
Add Comment
Please, Sign In to add comment