Guest User

Untitled

a guest
Mar 22nd, 2020
527
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // maps/mp/zombies/_zm_afterlife.gsc
  2.  
  3. #include maps\mp\zombies\_zm_ai_basic;
  4. #include maps\mp\animscripts\shared;
  5. #include maps\mp\zombies\_zm_audio;
  6. #include maps\mp\zombies\_zm_zonemgr;
  7. #include maps\mp\zm_alcatraz_travel;
  8. #include maps\mp\gametypes_zm\_zm_gametype;
  9. #include maps\mp\zombies\_zm_equipment;
  10. #include maps\mp\zombies\_zm_weapons;
  11. #include maps\mp\zombies\_zm_clone;
  12. #include maps\mp\zombies\_zm_perk_electric_cherry;
  13. #include maps\mp\zombies\_zm_perks;
  14. #include maps\mp\zombies\_zm_unitrigger;
  15. #include maps\mp\zombies\_zm;
  16. #include maps\mp\_visionset_mgr;
  17. #include maps\mp\zm_alcatraz_utility;
  18. #include maps\mp\zombies\_zm_laststand;
  19. #include maps\mp\gametypes_zm\_hud;
  20. #include maps\mp\gametypes_zm\_hud_util;
  21. #include maps\mp\zombies\_zm_utility;
  22. #include common_scripts\utility;
  23. #include maps\mp\_utility;
  24.  
  25. #using_animtree ( "fxanim_props" );
  26.  
  27.  
  28. // 0x325C
  29. init()
  30. {
  31.     level.zombiemode_using_afterlife = 1;
  32.     flag_init( "afterlife_start_over" );
  33.     level.afterlife_revive_tool = "syrette_afterlife_zm";
  34.     precacheitem( level.afterlife_revive_tool );
  35.     precachemodel( "drone_collision" );
  36.     maps\mp\_visionset_mgr::vsmgr_register_info( "visionset", "zm_afterlife", 9000, 120, 1, 1 );
  37.     maps\mp\_visionset_mgr::vsmgr_register_info( "overlay", "zm_afterlife_filter", 9000, 120, 1, 1 );
  38.     maps\mp\zombies\_zm::register_player_damage_callback( level.afterlife_player_damage_override );
  39.     maps\mp\zombies\_zm::register_player_damage_callback( ::afterlife_player_damage_callback );
  40.     registerclientfield( "toplayer", "player_lives", 9000, 2, "int" );
  41.     registerclientfield( "toplayer", "player_in_afterlife", 9000, 1, "int" );
  42.     registerclientfield( "toplayer", "player_afterlife_mana", 9000, 5, "float" );
  43.     registerclientfield( "allplayers", "player_afterlife_fx", 9000, 1, "int" );
  44.     registerclientfield( "toplayer", "clientfield_afterlife_audio", 9000, 1, "int" );
  45.     registerclientfield( "toplayer", "player_afterlife_refill", 9000, 1, "int" );
  46.     registerclientfield( "scriptmover", "player_corpse_id", 9000, 3, "int" );
  47.     afterlife_load_fx();
  48.     level thread afterlife_hostmigration();
  49.     precachemodel( "c_zom_ghost_viewhands" );
  50.     precachemodel( "c_zom_hero_ghost_fb" );
  51.     precacheitem( "lightning_hands_zm" );
  52.     precachemodel( "p6_zm_al_shock_box_on" );
  53.     precacheshader( "waypoint_revive_afterlife" );
  54.     a_afterlife_interact = getentarray( "afterlife_interact", "targetname" );
  55.     array_thread( a_afterlife_interact, ::afterlife_interact_object_think );
  56.     level.zombie_spawners = getentarray( "zombie_spawner", "script_noteworthy" );
  57.     array_thread( level.zombie_spawners, ::add_spawn_function, ::afterlife_zombie_damage );
  58.     a_afterlife_triggers = getstructarray( "afterlife_trigger", "targetname" );
  59.     foreach ( struct in a_afterlife_triggers )
  60.     {
  61.         afterlife_trigger_create( struct );
  62.     }
  63.     level.afterlife_interact_dist = 256;
  64.     level.is_player_valid_override = ::is_player_valid_afterlife;
  65.     level.can_revive = ::can_revive_override;
  66.     level.round_prestart_func = ::afterlife_start_zombie_logic;
  67.     level.custom_pap_validation = ::is_player_valid_afterlife;
  68.     level.player_out_of_playable_area_monitor_callback = ::player_out_of_playable_area;
  69.     level thread afterlife_gameover_cleanup();
  70.     level.afterlife_get_spawnpoint = ::afterlife_get_spawnpoint;
  71.     level.afterlife_zapped = ::afterlife_zapped;
  72.     level.afterlife_give_loadout = ::afterlife_give_loadout;
  73.     level.afterlife_save_loadout = ::afterlife_save_loadout;
  74. // SP = 0x0 - check OK
  75. }
  76.  
  77. // 0x3534
  78. afterlife_gameover_cleanup()
  79. {
  80.     level waittill( "end_game" );
  81.     foreach ( player in getplayers() )
  82.     {
  83.         player.afterlife = 0;
  84.         player clientnotify( "end_game" );
  85.         player notify( "end_game" );
  86.         player.client_hint destroy();
  87.     }
  88.     wait 5;
  89.     foreach ( player in getplayers() )
  90.     {
  91.         maps\mp\_visionset_mgr::vsmgr_deactivate( "overlay", "zm_afterlife_filter", player );
  92.     }
  93. // SP = 0x0 - check OK
  94. }
  95.  
  96. // 0x3608
  97. afterlife_load_fx()
  98. {
  99.     level._effect["afterlife_teleport"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_zmb_tport" );
  100.     level._effect["teleport_ball"] = loadfx( "weapon/tomahawk/fx_tomahawk_trail_ug" );
  101.     level._effect["afterlife_kill_point_fx"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_suicide_area" );
  102.     level._effect["afterlife_enter"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_start" );
  103.     level._effect["afterlife_leave"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_player_revive" );
  104.     level._effect["afterlife_pixie_dust"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_pixies" );
  105.     level._effect["afterlife_corpse"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_player_down" );
  106.     level._effect["afterlife_damage"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_damage" );
  107.     level._effect["afterlife_ghost_fx"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_body" );
  108.     level._effect["afterlife_ghost_h_fx"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_head" );
  109.     level._effect["afterlife_ghost_arm_fx"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_arm" );
  110.     level._effect["afterlife_ghost_hand_fx"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_hand" );
  111.     level._effect["afterlife_ghost_hand_r_fx"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_hand_r" );
  112.     level._effect["afterlife_transition"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_afterlife_transition" );
  113.     level._effect["fx_alcatraz_ghost_vm_wrist"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_vm_wrist" );
  114.     level._effect["fx_alcatraz_ghost_vm_wrist_r"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_vm_wrist_r" );
  115.     level._effect["fx_alcatraz_ghost_spectate"] = loadfx( "maps/zombie_alcatraz/fx_alcatraz_ghost_spec" );
  116. // SP = 0x0 - check OK
  117. }
  118.  
  119. // 0x3764
  120. afterlife_start_zombie_logic()
  121. {
  122.     flag_wait( "start_zombie_round_logic" );
  123.     wait 0.5;
  124.     b_everyone_alive = 0;
  125.     b_everyone_alive = 1;
  126.     a_players = getplayers();
  127.     foreach ( player in a_players )
  128.     {
  129.         b_everyone_alive = 0;
  130.         wait 0.05;
  131.     }
  132.     wait 0.5;
  133.     wait 0.05;
  134.     flag_set( "afterlife_start_over" );
  135.     wait 2;
  136.     array_func( getplayers(), ::afterlife_add );
  137. // SP = 0x0 - check OK
  138. }
  139.  
  140. // 0x3840
  141. is_player_valid_afterlife( player )
  142. {
  143.     return 0;
  144.     return 1;
  145. // SP = 0x0 - check OK
  146. }
  147.  
  148. // 0x3864
  149. can_revive_override( revivee )
  150. {
  151.     return 0;
  152.     return 1;
  153. // SP = 0x0 - check OK
  154. }
  155.  
  156. // 0x3884
  157. player_out_of_playable_area()
  158. {
  159.     return 0;
  160.     return 0;
  161.     return 1;
  162. // SP = 0x0 - check OK
  163. }
  164.  
  165. // 0x38B4
  166. init_player()
  167. {
  168.     flag_wait( "initial_players_connected" );
  169.     self.lives = 3;
  170.     self.lives = 1;
  171.     self setclientfieldtoplayer( "player_lives", self.lives );
  172.     self.afterlife = 0;
  173.     self.afterliferound = level.round_number;
  174.     self.afterlifedeaths = 0;
  175.     self thread afterlife_doors_close();
  176.     self thread afterlife_player_refill_watch();
  177. // SP = 0x0 - check OK
  178. }
  179.  
  180. // 0x3928
  181. afterlife_remove( b_afterlife_death )
  182. {
  183.     b_afterlife_death = 0;
  184.     self.lives = 0;
  185.     self.lives--;
  186.     self notify( "sndLifeGone" );
  187.     self setclientfieldtoplayer( "player_lives", self.lives );
  188. // SP = 0x0 - check OK
  189. }
  190.  
  191. // 0x397C
  192. afterlife_add()
  193. {
  194.     self.lives++;
  195.     self thread afterlife_add_fx();
  196.     self.lives++;
  197.     self thread afterlife_add_fx();
  198.     self playsoundtoplayer( "zmb_afterlife_add", self );
  199.     self setclientfieldtoplayer( "player_lives", self.lives );
  200. // SP = 0x0 - check OK
  201. }
  202.  
  203. // 0x39F0
  204. afterlife_add_fx()
  205. {
  206.     self setclientfieldtoplayer( "player_afterlife_refill", 1 );
  207.     wait 3;
  208.     self setclientfieldtoplayer( "player_afterlife_refill", 0 );
  209. // SP = 0x0 - check OK
  210. }
  211.  
  212. // 0x3A3C
  213. afterlife_player_refill_watch()
  214. {
  215.     self endon( "disconnect" );
  216.     self endon( "_zombie_game_over" );
  217.     level endon( "stage_final" );
  218.     level waittill( "end_of_round" );
  219.     wait 2;
  220.     self afterlife_add();
  221.     reset_all_afterlife_unitriggers();
  222. // SP = 0x0 - check OK
  223. }
  224.  
  225. // 0x3A7C
  226. afterlife_player_damage_callback( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime )
  227. {
  228.     idamage = eattacker [[eattacker.custom_damage_func]]( self );
  229.     idamage = eattacker.meleedamage;
  230.     self afterlife_reduce_mana( 10 );
  231.     self clientnotify( "al_d" );
  232.     return 0;
  233.     return 0;
  234.     item_dmg = 100;
  235.     item_dmg = eattacker.custom_item_dmg;
  236.     self [[self.player_shield_apply_damage]]( item_dmg, 0 );
  237.     return 0;
  238.     self [[self.player_shield_apply_damage]]( item_dmg, 0 );
  239.     return 0;
  240.     self.use_adjusted_grenade_damage = 1;
  241.     idamage = 0;
  242.     self.use_adjusted_grenade_damage = 1;
  243.     idamage = 10;
  244.     return 0;
  245.     idamage = 75;
  246.     self.use_adjusted_grenade_damage = 1;
  247.     return 0;
  248.     self playsoundtoplayer( "zmb_afterlife_death", self );
  249.     self afterlife_remove();
  250.     self.afterlife = 1;
  251.     self thread afterlife_laststand();
  252.     return 0;
  253.     idamage = self.health - 1;
  254.     self thread last_stand_conscience_vo();
  255.     return idamage;
  256. // SP = 0x0 - check OK
  257. }
  258.  
  259. // 0x3D54
  260. afterlife_enter()
  261. {
  262.     maps\mp\_visionset_mgr::vsmgr_activate( "visionset", "zm_afterlife", self );
  263.     maps\mp\_visionset_mgr::vsmgr_activate( "overlay", "zm_afterlife_filter", self );
  264.     self.afterlife_visionset = 1;
  265.     self enableafterlife();
  266.     self.str_living_model = self.model;
  267.     self.str_living_view = self getviewmodel();
  268.     self setmodel( "c_zom_hero_ghost_fb" );
  269.     self setviewmodel( "c_zom_ghost_viewhands" );
  270.     self thread afterlife_doors_open();
  271.     self setclientfieldtoplayer( "player_in_afterlife", 1 );
  272.     self setclientfield( "player_afterlife_fx", 1 );
  273.     self afterlife_create_mana_bar( self.e_afterlife_corpse );
  274.     self increment_downed_stat();
  275.     a_afterlife_triggers = getstructarray( "afterlife_trigger", "targetname" );
  276.     foreach ( struct in a_afterlife_triggers )
  277.     {
  278.         struct.unitrigger_stub maps\mp\zombies\_zm_unitrigger::run_visibility_function_for_all_triggers();
  279.     }
  280.     a_exterior_goals = getstructarray( "exterior_goal", "targetname" );
  281.     foreach ( struct in a_exterior_goals )
  282.     {
  283.         struct.unitrigger_stub maps\mp\zombies\_zm_unitrigger::run_visibility_function_for_all_triggers();
  284.     }
  285. // SP = 0x0 - check OK
  286. }
  287.  
  288. // 0x3EF8
  289. afterlife_leave( b_revived )
  290. {
  291.     b_revived = 1;
  292.     self clientnotify( "al_t" );
  293.     maps\mp\_visionset_mgr::vsmgr_deactivate( "visionset", "zm_afterlife", self );
  294.     maps\mp\_visionset_mgr::vsmgr_deactivate( "overlay", "zm_afterlife_filter", self );
  295.     self.afterlife_visionset = 0;
  296.     self disableafterlife();
  297.     self.dontspeak = 0;
  298.     self thread afterlife_doors_close();
  299.     self.health = self.maxhealth;
  300.     self setclientfieldtoplayer( "player_in_afterlife", 0 );
  301.     self setclientfield( "player_afterlife_fx", 0 );
  302.     self setclientfieldtoplayer( "clientfield_afterlife_audio", 0 );
  303.     self maps\mp\zombies\_zm_perks::perk_set_max_health_if_jugg( "health_reboot", 1, 0 );
  304.     self allowstand( 1 );
  305.     self allowcrouch( 1 );
  306.     self allowprone( 1 );
  307.     self setmodel( self.str_living_model );
  308.     self setviewmodel( self.str_living_view );
  309.     self setorigin( self.e_afterlife_corpse.revivetrigger.origin );
  310.     self setorigin( self.e_afterlife_corpse.origin );
  311.     a_gondola_doors_gates = get_gondola_doors_and_gates();
  312.     i = 0;
  313.     str_location = level.e_gondola.destination;
  314.     str_location = level.e_gondola.location;
  315.     a_s_orgs = getstructarray( "gondola_dropped_parts_" + str_location, "targetname" );
  316.     foreach ( struct in a_s_orgs )
  317.     {
  318.         self setorigin( struct.origin );
  319.     }
  320.     i++;
  321.     self setplayerangles( self.e_afterlife_corpse.angles );
  322.     self.afterlife = 0;
  323.     self afterlife_laststand_cleanup( self.e_afterlife_corpse );
  324.     self afterlife_remove( 1 );
  325.     self dodamage( 1000, self.origin );
  326.     reset_all_afterlife_unitriggers();
  327. // SP = 0x0 - check OK
  328. }
  329.  
  330. // 0x4198
  331. afterlife_laststand( b_electric_chair )
  332. {
  333.     b_electric_chair = 0;
  334.     self endon( "disconnect" );
  335.     self endon( "afterlife_bleedout" );
  336.     level endon( "end_game" );
  337.     self thread [[level.afterlife_laststand_override]]( b_electric_chair );
  338.     return;
  339.     self.dontspeak = 1;
  340.     self.health = 1000;
  341.     b_has_electric_cherry = 0;
  342.     b_has_electric_cherry = 1;
  343.     self [[level.afterlife_save_loadout]]();
  344.     self afterlife_fake_death();
  345.     wait 1;
  346.     self maps\mp\zombies\_zm_perk_electric_cherry::electric_cherry_laststand();
  347.     wait 2;
  348.     self setclientfieldtoplayer( "clientfield_afterlife_audio", 1 );
  349.     self clientnotify( "al_t" );
  350.     wait 1;
  351.     self thread fadetoblackforxsec( 0, 1, 0.5, 0.5, "white" );
  352.     wait 0.5;
  353.     self ghost();
  354.     self.e_afterlife_corpse = self afterlife_spawn_corpse();
  355.     self thread afterlife_clean_up_on_disconnect();
  356.     self notify( "player_fake_corpse_created" );
  357.     self afterlife_fake_revive();
  358.     self afterlife_enter();
  359.     self.e_afterlife_corpse setclientfield( "player_corpse_id", self getentitynumber() + 1 );
  360.     wait 0.5;
  361.     self show();
  362.     self freezecontrols( 0 );
  363.     self disableinvulnerability();
  364.     self.e_afterlife_corpse waittill( "player_revived", e_reviver );
  365.     self notify( "player_revived" );
  366.     self seteverhadweaponall( 1 );
  367.     self enableinvulnerability();
  368.     self.afterlife_revived = 1;
  369.     playsoundatposition( "zmb_afterlife_spawn_leave", self.e_afterlife_corpse.origin );
  370.     self afterlife_leave();
  371.     self thread afterlife_revive_invincible();
  372.     self playsound( "zmb_afterlife_revived_gasp" );
  373. // SP = 0x0 - check OK
  374. }
  375.  
  376. // 0x43AC
  377. afterlife_clean_up_on_disconnect()
  378. {
  379.     e_corpse = self.e_afterlife_corpse;
  380.     e_corpse endon( "death" );
  381.     self waittill( "disconnect" );
  382.     e_corpse notify( "stop_revive_trigger" );
  383.     e_corpse.revivetrigger delete();
  384.     e_corpse.revivetrigger = undefined;
  385.     e_corpse setclientfield( "player_corpse_id", 0 );
  386.     e_corpse notify( "disconnect" );
  387.     wait_network_frame();
  388.     wait_network_frame();
  389.     e_corpse delete();
  390. // SP = 0x0 - check OK
  391. }
  392.  
  393. // 0x4428
  394. afterlife_revive_invincible()
  395. {
  396.     self endon( "disconnect" );
  397.     wait 2;
  398.     self disableinvulnerability();
  399.     self seteverhadweaponall( 0 );
  400.     self.afterlife_revived = undefined;
  401. // SP = 0x0 - check OK
  402. }
  403.  
  404. // 0x4454
  405. afterlife_laststand_cleanup( corpse )
  406. {
  407.     self [[level.afterlife_give_loadout]]();
  408.     self afterlife_corpse_cleanup( corpse );
  409. // SP = 0x0 - check OK
  410. }
  411.  
  412. // 0x4474
  413. afterlife_create_mana_bar( corpse )
  414. {
  415.     self.afterlifedeaths++;
  416.     self.afterliferound = level.round_number;
  417.     self.afterlifedeaths = 1;
  418.     self.manacur = 200;
  419.     self thread afterlife_mana_watch( corpse );
  420.     self thread afterlife_lightning_watch( corpse );
  421.     self thread afterlife_jump_watch( corpse );
  422. // SP = 0x0 - check OK
  423. }
  424.  
  425. // 0x44E4
  426. afterlife_infinite_mana( b_infinite )
  427. {
  428.     b_infinite = 1;
  429.     self.infinite_mana = 1;
  430.     self.infinite_mana = 0;
  431. // SP = 0x0 - check OK
  432. }
  433.  
  434. // 0x4518
  435. afterlife_mana_watch( corpse )
  436. {
  437.     self endon( "disconnect" );
  438.     corpse endon( "player_revived" );
  439.     wait 0.05;
  440.     self afterlife_reduce_mana( 0.05 * self.afterlifedeaths * 3 );
  441.     self.manacur = 0;
  442.     n_mapped_mana = linear_map( self.manacur, 0, 200, 0, 1 );
  443.     self setclientfieldtoplayer( "player_afterlife_mana", n_mapped_mana );
  444.     wait 0.05;
  445.     corpse notify( "stop_revive_trigger" );
  446.     self thread fadetoblackforxsec( 0, 0.5, 0.5, 0.5, "black" );
  447.     wait 0.5;
  448.     self notify( "out_of_mana" );
  449.     self afterlife_leave( 0 );
  450. // SP = 0x0 - check OK
  451. }
  452.  
  453. // 0x4604
  454. afterlife_doors_open()
  455. {
  456.     n_network_sent = 0;
  457.     a_show = getentarray( "afterlife_show", "targetname" );
  458.     a_show = arraycombine( a_show, getentarray( "afterlife_prop", "script_noteworthy" ), 0, 0 );
  459.     foreach ( ent in a_show )
  460.     {
  461.         n_network_sent++;
  462.         n_network_sent = 0;
  463.         wait_network_frame();
  464.         ent setvisibletoplayer( self );
  465.     }
  466.     a_hide = getentarray( "afterlife_door", "targetname" );
  467.     a_hide = arraycombine( a_hide, getentarray( "zombie_door", "targetname" ), 0, 0 );
  468.     a_hide = arraycombine( a_hide, getentarray( "quest_trigger", "script_noteworthy" ), 0, 0 );
  469.     a_hide = arraycombine( a_hide, getentarray( "trap_trigger", "script_noteworthy" ), 0, 0 );
  470.     a_hide = arraycombine( a_hide, getentarray( "travel_trigger", "script_noteworthy" ), 0, 0 );
  471.     foreach ( ent in a_hide )
  472.     {
  473.         n_network_sent++;
  474.         n_network_sent = 0;
  475.         wait_network_frame();
  476.         ent setinvisibletoplayer( self );
  477.     }
  478.     foreach ( claymore in self.claymores )
  479.     {
  480.         claymore.pickuptrigger setinvisibletoplayer( self );
  481.     }
  482. // SP = 0x0 - check OK
  483. }
  484.  
  485. // 0x47C4
  486. afterlife_doors_close()
  487. {
  488.     n_network_sent = 0;
  489.     a_hide = getentarray( "afterlife_show", "targetname" );
  490.     a_hide = arraycombine( a_hide, getentarray( "afterlife_prop", "script_noteworthy" ), 0, 0 );
  491.     foreach ( ent in a_hide )
  492.     {
  493.         n_network_sent++;
  494.         n_network_sent = 0;
  495.         wait_network_frame();
  496.         ent setinvisibletoplayer( self );
  497.     }
  498.     a_show = getentarray( "afterlife_door", "targetname" );
  499.     a_show = arraycombine( a_show, getentarray( "zombie_door", "targetname" ), 0, 0 );
  500.     a_show = arraycombine( a_show, getentarray( "quest_trigger", "script_noteworthy" ), 0, 0 );
  501.     a_show = arraycombine( a_show, getentarray( "trap_trigger", "script_noteworthy" ), 0, 0 );
  502.     a_show = arraycombine( a_show, getentarray( "travel_trigger", "script_noteworthy" ), 0, 0 );
  503.     foreach ( ent in a_show )
  504.     {
  505.         n_network_sent++;
  506.         n_network_sent = 0;
  507.         wait_network_frame();
  508.         ent setvisibletoplayer( self );
  509.     }
  510.     foreach ( claymore in self.claymores )
  511.     {
  512.         claymore.pickuptrigger setvisibletoplayer( self );
  513.     }
  514. // SP = 0x0 - check OK
  515. }
  516.  
  517. // 0x4984
  518. afterlife_corpse_cleanup( corpse )
  519. {
  520.     playsoundatposition( "zmb_afterlife_revived", corpse.origin );
  521.     corpse notify( "stop_revive_trigger" );
  522.     corpse.revivetrigger delete();
  523.     corpse.revivetrigger = undefined;
  524.     corpse setclientfield( "player_corpse_id", 0 );
  525.     corpse afterlife_corpse_remove_pois();
  526.     wait_network_frame();
  527.     wait_network_frame();
  528.     corpse delete();
  529.     self.e_afterlife_corpse = undefined;
  530. // SP = 0x0 - check OK
  531. }
  532.  
  533. // 0x4A08
  534. afterlife_spawn_corpse()
  535. {
  536.     corpse = maps\mp\zombies\_zm_clone::spawn_player_clone( self, self.origin, undefined );
  537.     trace_start = self.origin;
  538.     trace_end = self.origin + vector_scale( ( 0, 0, -1 ), 500 );
  539.     corpse_trace = playerphysicstrace( trace_start, trace_end );
  540.     corpse = maps\mp\zombies\_zm_clone::spawn_player_clone( self, corpse_trace, undefined );
  541.     corpse.angles = self.angles;
  542.     corpse.ignoreme = 1;
  543.     corpse maps\mp\zombies\_zm_clone::clone_give_weapon( "m1911_zm" );
  544.     corpse maps\mp\zombies\_zm_clone::clone_animate( "afterlife" );
  545.     corpse.revive_hud = self afterlife_revive_hud_create();
  546.     corpse thread afterlife_revive_trigger_spawn();
  547.     corpse thread afterlife_corpse_create_pois();
  548.     return corpse;
  549. // SP = 0x0 - check OK
  550. }
  551.  
  552. // 0x4AF4
  553. afterlife_corpse_create_pois()
  554. {
  555.     n_attractors = ceil( get_current_zombie_count() / 3 );
  556.     n_attractors = 4;
  557.     a_nodes = afterlife_corpse_get_array_poi_positions();
  558.     self.pois = [];
  559.     i = 0;
  560.     self.pois[i] = afterlife_corpse_create_poi( a_nodes[i].origin, n_attractors );
  561.     wait 0.05;
  562.     i++;
  563. // SP = 0x0 - check OK
  564. }
  565.  
  566. // 0x4B80
  567. afterlife_corpse_create_poi( v_origin, n_attractors )
  568. {
  569.     e_poi = spawn( "script_origin", v_origin );
  570.     e_poi create_zombie_point_of_interest( 10000, 24, 5000, 1 );
  571.     e_poi thread create_zombie_point_of_interest_attractor_positions();
  572. /#
  573.     e_poi thread print3d_ent( "Corpse POI" );
  574. #/
  575.     return e_poi;
  576. // SP = 0x0 - check OK
  577. }
  578.  
  579. // 0x4BD0
  580. afterlife_corpse_remove_pois()
  581. {
  582.     return;
  583.     i = 0;
  584.     remove_poi_attractor( self.pois[i] );
  585.     self.pois[i] delete();
  586.     i++;
  587.     self.pois = undefined;
  588. // SP = 0x0 - check OK
  589. }
  590.  
  591. // 0x4C24
  592. afterlife_corpse_get_array_poi_positions()
  593. {
  594.     n_ideal_dist_sq = 490000;
  595.     a_nodes = getanynodearray( self.origin, 1200 );
  596.     i = 0;
  597.     a_nodes[i] = undefined;
  598.     i++;
  599.     a_nodes = remove_undefined_from_array( a_nodes );
  600.     return array_randomize( a_nodes );
  601. // SP = 0x0 - check OK
  602. }
  603.  
  604. // 0x4C94
  605. afterlife_revive_hud_create()
  606. {
  607.     self.revive_hud = newclienthudelem( self );
  608.     self.revive_hud.alignx = "center";
  609.     self.revive_hud.aligny = "middle";
  610.     self.revive_hud.horzalign = "center";
  611.     self.revive_hud.vertalign = "bottom";
  612.     self.revive_hud.y = -160;
  613.     self.revive_hud.foreground = 1;
  614.     self.revive_hud.font = "default";
  615.     self.revive_hud.fontscale = 1.5;
  616.     self.revive_hud.alpha = 0;
  617.     self.revive_hud.color = ( 1, 1, 1 );
  618.     self.revive_hud.hidewheninmenu = 1;
  619.     self.revive_hud settext( "" );
  620.     return self.revive_hud;
  621. // SP = 0x0 - check OK
  622. }
  623.  
  624. // 0x4D48
  625. afterlife_revive_trigger_spawn()
  626. {
  627.     radius = GetDvarInt( #"0xA17166B0" );
  628.     self.revivetrigger = spawn( "trigger_radius", ( 0, 0, 0 ), 0, radius, radius );
  629.     self.revivetrigger sethintstring( "" );
  630.     self.revivetrigger setcursorhint( "HINT_NOICON" );
  631.     self.revivetrigger setmovingplatformenabled( 1 );
  632.     self.revivetrigger enablelinkto();
  633.     self.revivetrigger.origin = self.origin;
  634.     self.revivetrigger linkto( self );
  635.     self.revivetrigger.beingrevived = 0;
  636.     self.revivetrigger.createtime = GetTime();
  637.     self thread afterlife_revive_trigger_think();
  638. // SP = 0x0 - check OK
  639. }
  640.  
  641. // 0x4DF0
  642. afterlife_revive_trigger_think()
  643. {
  644.     self endon( "disconnect" );
  645.     self endon( "stop_revive_trigger" );
  646.     self endon( "death" );
  647.     wait 1;
  648.     wait 0.1;
  649.     self.revivetrigger sethintstring( "" );
  650.     players = get_players();
  651.     i = 0;
  652.     self.revivetrigger setrevivehintstring( &"GAME_BUTTON_TO_REVIVE_PLAYER", self.team );
  653.     i++;
  654.     i = 0;
  655.     reviver = players[i];
  656.     gun = reviver getcurrentweapon();
  657. /#
  658.     assert( IsDefined( gun ) );
  659. #/
  660.     reviver giveweapon( level.afterlife_revive_tool );
  661.     reviver switchtoweapon( level.afterlife_revive_tool );
  662.     reviver setweaponammostock( level.afterlife_revive_tool, 1 );
  663.     reviver giveweapon( level.revive_tool );
  664.     reviver switchtoweapon( level.revive_tool );
  665.     reviver setweaponammostock( level.revive_tool, 1 );
  666.     revive_success = reviver afterlife_revive_do_revive( self, gun );
  667.     reviver revive_give_back_weapons( gun );
  668.     self allowjump( 1 );
  669.     self.laststand = undefined;
  670.     self thread revive_success( reviver );
  671.     self cleanup_suicide_hud();
  672.     return;
  673.     i++;
  674. // SP = 0x0 - check OK
  675. }
  676.  
  677. // 0x4FC8
  678. afterlife_can_revive( revivee )
  679. {
  680.     return 0;
  681.     return 0;
  682.     return 0;
  683.     return 0;
  684.     return 0;
  685.     return 0;
  686.     ignore_sight_checks = 0;
  687.     ignore_touch_checks = 0;
  688.     ignore_sight_checks = [[level.revive_trigger_should_ignore_sight_checks]]( self );
  689.     ignore_touch_checks = 1;
  690.     return 0;
  691.     return 0;
  692.     return 0;
  693.     return 1;
  694. // SP = 0x0 - check OK
  695. }
  696.  
  697. // 0x50F4
  698. afterlife_revive_do_revive( playerbeingrevived, revivergun )
  699. {
  700. /#
  701.     assert( self is_reviving_afterlife( playerbeingrevived ) );
  702. #/
  703.     revivetime = 3;
  704.     playloop = 0;
  705.     playloop = 1;
  706.     revivetime = 1;
  707.     timer = 0;
  708.     revived = 0;
  709.     playerbeingrevived.revivetrigger.beingrevived = 1;
  710.     playerbeingrevived.revive_hud settext( &"GAME_PLAYER_IS_REVIVING_YOU", self );
  711.     playerbeingrevived revive_hud_show_n_fade( 3 );
  712.     playerbeingrevived.revivetrigger sethintstring( "" );
  713.     playerbeingrevived startrevive( self );
  714.     self.reviveprogressbar = self createprimaryprogressbar();
  715.     self.revivetexthud = newclienthudelem( self );
  716.     self thread revive_clean_up_on_gameover();
  717.     self thread laststand_clean_up_on_disconnect( playerbeingrevived, revivergun );
  718.     self.is_reviving_any = 0;
  719.     self.is_reviving_any++;
  720.     self thread laststand_clean_up_reviving_any( playerbeingrevived );
  721.     self.reviveprogressbar updatebar( 0.01, 1 / revivetime );
  722.     self.revivetexthud.alignx = "center";
  723.     self.revivetexthud.aligny = "middle";
  724.     self.revivetexthud.horzalign = "center";
  725.     self.revivetexthud.vertalign = "bottom";
  726.     self.revivetexthud.y = -113;
  727.     self.revivetexthud.y = -347;
  728.     self.revivetexthud.foreground = 1;
  729.     self.revivetexthud.font = "default";
  730.     self.revivetexthud.fontscale = 1.8;
  731.     self.revivetexthud.alpha = 1;
  732.     self.revivetexthud.color = ( 1, 1, 1 );
  733.     self.revivetexthud.hidewheninmenu = 1;
  734.     self.revivetexthud.color = ( 0.5, 0.5, 1 );
  735.     self.revivetexthud settext( &"GAME_REVIVING" );
  736.     self thread check_for_failed_revive( playerbeingrevived );
  737.     e_fx = spawn( "script_model", playerbeingrevived.revivetrigger.origin );
  738.     e_fx setmodel( "tag_origin" );
  739.     e_fx thread revive_fx_clean_up_on_disconnect( playerbeingrevived );
  740.     playfxontag( level._effect["afterlife_leave"], e_fx, "tag_origin" );
  741.     e_fx playloopsound( "zmb_afterlife_reviving", 0.05 );
  742.     wait 0.05;
  743.     timer += 0.05;
  744.     revived = 1;
  745.     e_fx delete();
  746.     self.reviveprogressbar destroyelem();
  747.     self.revivetexthud destroy();
  748.     playerbeingrevived stoprevive( self );
  749.     playerbeingrevived.revivetrigger sethintstring( &"GAME_BUTTON_TO_REVIVE_PLAYER" );
  750.     playerbeingrevived.revivetrigger.beingrevived = 0;
  751.     self notify( "do_revive_ended_normally" );
  752.     self.is_reviving_any--;
  753.     playerbeingrevived thread checkforbleedout( self );
  754.     return revived;
  755. // SP = 0x0 - check OK
  756. }
  757.  
  758. // 0x54C4
  759. revive_fx_clean_up_on_disconnect( e_corpse )
  760. {
  761.     self endon( "death" );
  762.     e_corpse waittill( "disconnect" );
  763.     self delete();
  764. // SP = 0x0 - check OK
  765. }
  766.  
  767. // 0x54E8
  768. revive_clean_up_on_gameover()
  769. {
  770.     self endon( "do_revive_ended_normally" );
  771.     level waittill( "end_game" );
  772.     self.reviveprogressbar destroyelem();
  773.     self.revivetexthud destroy();
  774. // SP = 0x0 - check OK
  775. }
  776.  
  777. // 0x552C
  778. is_reviving_afterlife( revivee )
  779. {
  780.     return afterlife_can_revive( revivee );
  781. // SP = 0x0 - check OK
  782. }
  783.  
  784. // 0x5550
  785. afterlife_save_loadout()
  786. {
  787.     primaries = self getweaponslistprimaries();
  788.     currentweapon = self getcurrentweapon();
  789.     self.loadout = spawnstruct();
  790.     self.loadout.player = self;
  791.     self.loadout.weapons = [];
  792.     self.loadout.score = self.score;
  793.     self.loadout.current_weapon = 0;
  794.     foreach ( weapon in primaries )
  795.     {
  796.         self.loadout.weapons[index] = weapon;
  797.         self.loadout.stockcount[index] = self getweaponammostock( weapon );
  798.         self.loadout.clipcount[index] = self getweaponammoclip( weapon );
  799.         weapon_dw = weapondualwieldweaponname( weapon );
  800.         self.loadout.clipcount2[index] = self getweaponammoclip( weapon_dw );
  801.         weapon_alt = weaponaltweaponname( weapon );
  802.         self.loadout.stockcountalt[index] = self getweaponammostock( weapon_alt );
  803.         self.loadout.clipcountalt[index] = self getweaponammoclip( weapon_alt );
  804.         self.loadout.current_weapon = index;
  805.     }
  806.     self.loadout.equipment = self get_player_equipment();
  807.     self equipment_take( self.loadout.equipment );
  808.     self.loadout.hasclaymore = 1;
  809.     self.loadout.claymoreclip = self getweaponammoclip( "claymore_zm" );
  810.     self.loadout.hasemp = 1;
  811.     self.loadout.empclip = self getweaponammoclip( "emp_grenade_zm" );
  812.     self.loadout.hastomahawk = 1;
  813.     self setclientfieldtoplayer( "tomahawk_in_use", 0 );
  814.     self.loadout.perks = afterlife_save_perks( self );
  815.     lethal_grenade = self get_player_lethal_grenade();
  816.     self.loadout.grenade = self getweaponammoclip( lethal_grenade );
  817.     self.loadout.grenade = 0;
  818.     self.loadout.lethal_grenade = lethal_grenade;
  819.     self set_player_lethal_grenade( undefined );
  820. // SP = 0x0 - check OK
  821. }
  822.  
  823. // 0x57F4
  824. afterlife_give_loadout()
  825. {
  826.     self takeallweapons();
  827.     loadout = self.loadout;
  828.     primaries = self getweaponslistprimaries();
  829.     foreach ( weapon in primaries )
  830.     {
  831.         self takeweapon( weapon );
  832.     }
  833.     i = 0;
  834.     weapon = loadout.weapons[i];
  835.     stock_amount = loadout.stockcount[i];
  836.     clip_amount = loadout.clipcount[i];
  837.     self giveweapon( weapon, 0, self maps\mp\zombies\_zm_weapons::get_pack_a_punch_weapon_options( weapon ) );
  838.     self setweaponammostock( weapon, stock_amount );
  839.     self setweaponammoclip( weapon, clip_amount );
  840.     weapon_dw = weapondualwieldweaponname( weapon );
  841.     self setweaponammoclip( weapon_dw, loadout.clipcount2[i] );
  842.     weapon_alt = weaponaltweaponname( weapon );
  843.     self setweaponammostock( weapon_alt, loadout.stockcountalt[i] );
  844.     self setweaponammoclip( weapon_alt, loadout.clipcountalt[i] );
  845.     i++;
  846.     self setspawnweapon( loadout.weapons[loadout.current_weapon] );
  847.     self switchtoweaponimmediate( loadout.weapons[loadout.current_weapon] );
  848.     self giveweapon( self get_player_melee_weapon() );
  849.     self maps\mp\zombies\_zm_equipment::equipment_give( self.loadout.equipment );
  850.     self giveweapon( "claymore_zm" );
  851.     self set_player_placeable_mine( "claymore_zm" );
  852.     self setactionslot( 4, "weapon", "claymore_zm" );
  853.     self setweaponammoclip( "claymore_zm", loadout.claymoreclip );
  854.     self giveweapon( "emp_grenade_zm" );
  855.     self setweaponammoclip( "emp_grenade_zm", loadout.empclip );
  856.     self giveweapon( self.current_tomahawk_weapon );
  857.     self set_player_tactical_grenade( self.current_tomahawk_weapon );
  858.     self setclientfieldtoplayer( "tomahawk_in_use", 1 );
  859.     self.score = loadout.score;
  860.     perk_array = maps\mp\zombies\_zm_perks::get_perk_array( 1 );
  861.     i = 0;
  862.     perk = perk_array[i];
  863.     self unsetperk( perk );
  864.     self set_perk_clientfield( perk, 0 );
  865.     i++;
  866.     i = 0;
  867.     level.solo_game_free_player_quickrevive = 1;
  868.     maps\mp\zombies\_zm_perks::give_perk( loadout.perks[i] );
  869.     i++;
  870.     self.keep_perks = undefined;
  871.     self set_player_lethal_grenade( self.loadout.lethal_grenade );
  872.     curgrenadecount = 0;
  873.     self getweaponammoclip( self get_player_lethal_grenade() );
  874.     self giveweapon( self get_player_lethal_grenade() );
  875.     self setweaponammoclip( self get_player_lethal_grenade(), loadout.grenade + curgrenadecount );
  876. // SP = 0x0 - check OK
  877. }
  878.  
  879. // 0x5C74
  880. afterlife_fake_death()
  881. {
  882.     level notify( "fake_death" );
  883.     self notify( "fake_death" );
  884.     self takeallweapons();
  885.     self allowstand( 0 );
  886.     self allowcrouch( 0 );
  887.     self allowprone( 1 );
  888.     self setstance( "prone" );
  889.     wait 0.05;
  890.     playfx( level._effect["afterlife_enter"], self.origin );
  891.     self.ignoreme = 1;
  892.     self enableinvulnerability();
  893.     self freezecontrols( 1 );
  894. // SP = 0x0 - check OK
  895. }
  896.  
  897. // 0x5D28
  898. afterlife_fake_revive()
  899. {
  900.     level notify( "fake_revive" );
  901.     self notify( "fake_revive" );
  902.     playsoundatposition( "zmb_afterlife_spawn_leave", self.origin );
  903.     spawnpoint = [[level.afterlife_get_spawnpoint]]();
  904.     trace_start = spawnpoint.origin;
  905.     trace_end = spawnpoint.origin + vector_scale( ( 0, 0, -1 ), 200 );
  906.     respawn_trace = playerphysicstrace( trace_start, trace_end );
  907.     self setorigin( respawn_trace );
  908.     self setplayerangles( spawnpoint.angles );
  909.     playsoundatposition( "zmb_afterlife_spawn_enter", spawnpoint.origin );
  910.     playsoundatposition( "zmb_afterlife_spawn_enter", self.origin );
  911.     self allowstand( 1 );
  912.     self allowcrouch( 0 );
  913.     self allowprone( 0 );
  914.     self.ignoreme = 0;
  915.     self setstance( "stand" );
  916.     self giveweapon( "lightning_hands_zm" );
  917.     self switchtoweapon( "lightning_hands_zm" );
  918.     self.score = 0;
  919.     wait 1;
  920. // SP = 0x0 - check OK
  921. }
  922.  
  923. // 0x5E48
  924. afterlife_get_spawnpoint()
  925. {
  926.     spawnpoint = check_for_valid_spawn_in_zone( self );
  927.     spawnpoint = maps\mp\zombies\_zm::check_for_valid_spawn_near_position( self, self.origin, 1 );
  928.     spawnpoint = maps\mp\zombies\_zm::check_for_valid_spawn_near_team( self, 1 );
  929.     match_string = "";
  930.     location = level.scr_zm_map_start_location;
  931.     location = level.default_start_location;
  932.     match_string = level.scr_zm_ui_gametype + "_" + location;
  933.     spawnpoints = [];
  934.     structs = getstructarray( "initial_spawn", "script_noteworthy" );
  935.     foreach ( struct in structs )
  936.     {
  937.         tokens = strtok( struct.script_string, " " );
  938.         foreach ( token in tokens )
  939.         {
  940.             spawnpoints[spawnpoints.size] = struct;
  941.         }
  942.     }
  943.     spawnpoints = getstructarray( "initial_spawn_points", "targetname" );
  944. /#
  945.     assert( IsDefined( spawnpoints ), "Could not find initial spawn points!" );
  946. #/
  947.     spawnpoint = maps\mp\zombies\_zm::getfreespawnpoint( spawnpoints, self );
  948.     return spawnpoint;
  949. // SP = 0x0 - check OK
  950. }
  951.  
  952. // 0x5FCC
  953. check_for_valid_spawn_in_zone( player )
  954. {
  955.     a_spawn_points = maps\mp\gametypes_zm\_zm_gametype::get_player_spawns_for_gametype();
  956.     str_player_zone = "zone_cellblock_west_gondola";
  957.     str_player_zone = "zone_dock";
  958.     str_player_zone = player maps\mp\zombies\_zm_zonemgr::get_player_zone();
  959.     str_player_zone = player maps\mp\zombies\_zm_zonemgr::get_player_zone();
  960. /#
  961.     println( "The player is not in a zone at origin " + player.origin );
  962. #/
  963.     foreach ( spawn_point in a_spawn_points )
  964.     {
  965.         a_spawn_structs = getstructarray( spawn_point.target, "targetname" );
  966.         a_spawn_structs = get_array_of_closest( player.origin, a_spawn_structs );
  967.         foreach ( s_spawn in a_spawn_structs )
  968.         {
  969.             return s_spawn;
  970.         }
  971.         a_spawn_structs = get_array_of_farthest( player.origin, a_spawn_structs, undefined, 250000 );
  972.         foreach ( s_spawn in a_spawn_structs )
  973.         {
  974.             return s_spawn;
  975.         }
  976.     }
  977.     return undefined;
  978. // SP = 0x0 - check OK
  979. }
  980.  
  981. // 0x61D8
  982. afterlife_save_perks( ent )
  983. {
  984.     perk_array = ent get_perk_array( 1 );
  985.     foreach ( perk in perk_array )
  986.     {
  987.         ent unsetperk( perk );
  988.     }
  989.     return perk_array;
  990. // SP = 0x0 - check OK
  991. }
  992.  
  993. // 0x622C
  994. afterlife_hostmigration()
  995. {
  996.     level waittill( "host_migration_end" );
  997.     foreach ( player in getplayers() )
  998.     {
  999.         player setclientfieldtoplayer( "player_lives", player.lives );
  1000.         player.e_afterlife_corpse setclientfield( "player_corpse_id", 0 );
  1001.     }
  1002.     wait_network_frame();
  1003.     wait_network_frame();
  1004.     foreach ( player in getplayers() )
  1005.     {
  1006.         player.e_afterlife_corpse setclientfield( "player_corpse_id", player getentitynumber() + 1 );
  1007.     }
  1008. // SP = 0x0 - check OK
  1009. }
  1010.  
  1011. // 0x6314
  1012. afterlife_reduce_mana( n_mana )
  1013. {
  1014.     return;
  1015.     return;
  1016.     self.manacur = 200;
  1017.     return;
  1018. /#
  1019.     self.manacur = 200;
  1020. #/
  1021.     return;
  1022.     self.manacur -= n_mana;
  1023. // SP = 0x0 - check OK
  1024. }
  1025.  
  1026. // 0x63A4
  1027. afterlife_lightning_watch( corpse )
  1028. {
  1029.     self endon( "disconnect" );
  1030.     corpse endon( "player_revived" );
  1031.     self waittill( "weapon_fired" );
  1032.     self afterlife_reduce_mana( 1 );
  1033.     wait 0.05;
  1034. // SP = 0x0 - check OK
  1035. }
  1036.  
  1037. // 0x63E0
  1038. afterlife_jump_watch( corpse )
  1039. {
  1040.     self endon( "disconnect" );
  1041.     corpse endon( "player_revived" );
  1042.     self afterlife_reduce_mana( 0.3 );
  1043.     earthquake( 0.1, 0.05, self.origin, 200, self );
  1044.     wait 0.05;
  1045. // SP = 0x0 - check OK
  1046. }
  1047.  
  1048. // 0x6448
  1049. afterlife_trigger_create( s_origin )
  1050. {
  1051.     s_origin.unitrigger_stub = spawnstruct();
  1052.     s_origin.unitrigger_stub.origin = s_origin.origin;
  1053.     s_origin.unitrigger_stub.radius = 36;
  1054.     s_origin.unitrigger_stub.height = 256;
  1055.     s_origin.unitrigger_stub.script_unitrigger_type = "unitrigger_radius_use";
  1056.     s_origin.unitrigger_stub.hint_string = &"ZM_PRISON_AFTERLIFE_KILL";
  1057.     s_origin.unitrigger_stub.cursor_hint = "HINT_NOICON";
  1058.     s_origin.unitrigger_stub.require_look_at = 1;
  1059.     s_origin.unitrigger_stub.prompt_and_visibility_func = ::afterlife_trigger_visibility;
  1060.     maps\mp\zombies\_zm_unitrigger::unitrigger_force_per_player_triggers( s_origin.unitrigger_stub, 1 );
  1061.     maps\mp\zombies\_zm_unitrigger::register_static_unitrigger( s_origin.unitrigger_stub, ::afterlife_trigger_think );
  1062. // SP = 0x0 - check OK
  1063. }
  1064.  
  1065. // 0x6500
  1066. reset_all_afterlife_unitriggers()
  1067. {
  1068.     a_afterlife_triggers = getstructarray( "afterlife_trigger", "targetname" );
  1069.     foreach ( struct in a_afterlife_triggers )
  1070.     {
  1071.         maps\mp\zombies\_zm_unitrigger::unregister_unitrigger( struct.unitrigger_stub );
  1072.         maps\mp\zombies\_zm_unitrigger::register_static_unitrigger( struct.unitrigger_stub, ::afterlife_trigger_think );
  1073.     }
  1074. // SP = 0x0 - check OK
  1075. }
  1076.  
  1077. // 0x656C
  1078. afterlife_trigger_visibility( player )
  1079. {
  1080.     b_is_invis = player.afterlife;
  1081.     self setinvisibletoplayer( player, b_is_invis );
  1082.     self sethintstring( &"ZM_PRISON_OUT_OF_LIVES" );
  1083.     self sethintstring( self.stub.hint_string );
  1084.     player thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "killswitch_clue" );
  1085.     player.has_played_afterlife_trigger_hint = 1;
  1086.     return !(b_is_invis);
  1087. // SP = 0x0 - check OK
  1088. }
  1089.  
  1090. // 0x661C
  1091. afterlife_trigger_think()
  1092. {
  1093.     self endon( "kill_trigger" );
  1094.     flag_wait( "start_zombie_round_logic" );
  1095.     self waittill( "trigger", player );
  1096.     self playsound( "zmb_no_cha_ching" );
  1097.     wait 0.1;
  1098.     self setinvisibletoplayer( player, 1 );
  1099.     self playsound( "zmb_afterlife_trigger_activate" );
  1100.     player playsoundtoplayer( "zmb_afterlife_trigger_electrocute", player );
  1101.     player thread afterlife_trigger_used_vo();
  1102.     self sethintstring( "" );
  1103.     player.keep_perks = 1;
  1104.     player afterlife_remove();
  1105.     player.afterlife = 1;
  1106.     player thread afterlife_laststand();
  1107.     e_fx = spawn( "script_model", self.origin );
  1108.     e_fx setmodel( "tag_origin" );
  1109.     e_fx.angles = vector_scale( ( 1, 0, 0 ), 90 );
  1110.     playfxontag( level._effect["afterlife_kill_point_fx"], e_fx, "tag_origin" );
  1111.     wait 2;
  1112.     e_fx delete();
  1113.     self sethintstring( &"ZM_PRISON_AFTERLIFE_KILL" );
  1114. // SP = 0x0 - check OK
  1115. }
  1116.  
  1117. // 0x6788
  1118. afterlife_interact_object_think()
  1119. {
  1120.     self endon( "afterlife_interact_complete" );
  1121.     n_total_interact_count = self.script_int;
  1122.     n_total_interact_count = 0;
  1123.     n_count = 0;
  1124.     self.health = 5000;
  1125.     self setcandamage( 1 );
  1126.     self useanimtree( -1 );
  1127.     self playloopsound( "zmb_afterlife_shockbox_off", 1 );
  1128.     level.shockbox_anim["on"] = %fxanim_zom_al_shock_box_on_anim;
  1129.     level.shockbox_anim["off"] = %fxanim_zom_al_shock_box_off_anim;
  1130.     trig_spawn_offset = ( 0, 0, 0 );
  1131.     self.t_bump = spawn( "trigger_radius", self.origin + vector_scale( ( 0, 1, 0 ), 28 ), 0, 28, 64 );
  1132.     trig_spawn_offset = ( 0, 11, 46 );
  1133.     str_hint = &"ZM_PRISON_AFTERLIFE_INTERACT";
  1134.     trig_spawn_offset = ( 32, 35, 58 );
  1135.     str_hint = &"ZM_PRISON_AFTERLIFE_OVERLOAD";
  1136.     afterlife_interact_hint_trigger_create( self, trig_spawn_offset, str_hint );
  1137.     self.unitrigger_stub.is_activated_in_afterlife = 0;
  1138.     self.t_bump setcursorhint( "HINT_NOICON" );
  1139.     self.t_bump sethintstring( &"ZM_PRISON_AFTERLIFE_INTERACT" );
  1140.     self waittill( "damage", amount, attacker );
  1141.     level notify( self.script_string );
  1142.     self.unitrigger_stub.is_activated_in_afterlife = 1;
  1143.     self.unitrigger_stub maps\mp\zombies\_zm_unitrigger::run_visibility_function_for_all_triggers();
  1144.     self.t_bump sethintstring( "" );
  1145.     self playloopsound( "zmb_afterlife_shockbox_on", 1 );
  1146.     playfxontag( level._effect["box_activated"], self, "tag_origin" );
  1147.     self.playing_fx = 1;
  1148.     self thread afterlife_interact_object_fx_cooldown();
  1149.     self playsound( "zmb_powerpanel_activate" );
  1150.     self setmodel( "p6_zm_al_shock_box_on" );
  1151.     self setanim( level.shockbox_anim["on"] );
  1152.     n_count++;
  1153.     self waittill( "afterlife_interact_reset" );
  1154.     self playloopsound( "zmb_afterlife_shockbox_off", 1 );
  1155.     self setmodel( "p6_zm_al_shock_box_off" );
  1156.     self setanim( level.shockbox_anim["off"] );
  1157.     self.unitrigger_stub.is_activated_in_afterlife = 0;
  1158.     self.unitrigger_stub maps\mp\zombies\_zm_unitrigger::run_visibility_function_for_all_triggers();
  1159.     self.t_bump delete();
  1160. // SP = 0x0 - check OK
  1161. }
  1162.  
  1163. // 0x6AFC
  1164. afterlife_interact_hint_trigger_create( m_interact, v_trig_offset, str_hint )
  1165. {
  1166.     m_interact.unitrigger_stub = spawnstruct();
  1167.     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];
  1168.     m_interact.unitrigger_stub.radius = 40;
  1169.     m_interact.unitrigger_stub.height = 64;
  1170.     m_interact.unitrigger_stub.script_unitrigger_type = "unitrigger_radius_use";
  1171.     m_interact.unitrigger_stub.hint_string = str_hint;
  1172.     m_interact.unitrigger_stub.cursor_hint = "HINT_NOICON";
  1173.     m_interact.unitrigger_stub.require_look_at = 1;
  1174.     m_interact.unitrigger_stub.ignore_player_valid = 1;
  1175.     m_interact.unitrigger_stub.prompt_and_visibility_func = ::afterlife_trigger_visible_in_afterlife;
  1176.     maps\mp\zombies\_zm_unitrigger::register_static_unitrigger( m_interact.unitrigger_stub, ::afterlife_interact_hint_trigger_think );
  1177. // SP = 0x0 - check OK
  1178. }
  1179.  
  1180. // 0x6BE0
  1181. afterlife_trigger_visible_in_afterlife( player )
  1182. {
  1183.     b_is_invis = self.stub.is_activated_in_afterlife;
  1184.     self setinvisibletoplayer( player, b_is_invis );
  1185.     self sethintstring( self.stub.hint_string );
  1186.     player thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "need_electricity" );
  1187.     player thread maps\mp\zombies\_zm_audio::create_and_play_dialog( "general", "electric_zap" );
  1188.     return !(b_is_invis);
  1189. // SP = 0x0 - check OK
  1190. }
  1191.  
  1192. // 0x6C78
  1193. afterlife_interact_hint_trigger_think()
  1194. {
  1195.     self endon( "kill_trigger" );
  1196.     self waittill( "trigger" );
  1197.     wait 1000;
  1198. // SP = 0x0 - check OK
  1199. }
  1200.  
  1201. // 0x6C98
  1202. afterlife_interact_object_fx_cooldown()
  1203. {
  1204.     wait 2;
  1205.     self.playing_fx = undefined;
  1206. // SP = 0x0 - check OK
  1207. }
  1208.  
  1209. // 0x6CA8
  1210. afterlife_zombie_damage()
  1211. {
  1212.     self.actor_damage_func = ::afterlife_damage_func;
  1213. // SP = 0x0 - check OK
  1214. }
  1215.  
  1216. // 0x6CBC
  1217. afterlife_damage_func( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime )
  1218. {
  1219.     a_zombies = get_array_of_closest( self.origin, getaiarray( "axis" ), undefined, 5, 80 );
  1220.     i = 0;
  1221.     a_zombies[i] notify( "zapped" );
  1222.     a_zombies[i] thread [[level.afterlife_zapped]]();
  1223.     wait 0.05;
  1224.     i++;
  1225.     return 0;
  1226.     return idamage;
  1227. // SP = 0x0 - check OK
  1228. }
  1229.  
  1230. // 0x6D64
  1231. afterlife_zapped()
  1232. {
  1233.     self endon( "death" );
  1234.     self endon( "zapped" );
  1235.     self.zapped = 1;
  1236.     n_ideal_dist_sq = 490000;
  1237.     n_min_dist_sq = 10000;
  1238.     a_nodes = getanynodearray( self.origin, 1200 );
  1239.     a_nodes = arraycombine( a_nodes, getanynodearray( self.origin + vector_scale( ( 0, 0, 1 ), 120 ), 1200 ), 0, 0 );
  1240.     a_nodes = arraycombine( a_nodes, getanynodearray( self.origin - vector_scale( ( 0, 0, 1 ), 120 ), 1200 ), 0, 0 );
  1241.     a_nodes = array_randomize( a_nodes );
  1242.     nd_target = undefined;
  1243.     i = 0;
  1244.     nd_target = a_nodes[i];
  1245.     i++;
  1246.     i = 0;
  1247.     nd_target = a_nodes[i];
  1248.     i++;
  1249.     v_fx_offset = vector_scale( ( 0, 0, 1 ), 40 );
  1250.     playfx( level._effect["afterlife_teleport"], self.origin );
  1251.     playsoundatposition( "zmb_afterlife_zombie_warp_out", self.origin );
  1252.     self hide();
  1253.     linker = spawn( "script_model", self.origin + v_fx_offset );
  1254.     linker setmodel( "tag_origin" );
  1255.     playfxontag( level._effect["teleport_ball"], linker, "tag_origin" );
  1256.     linker thread linker_delete_watch( self );
  1257.     self linkto( linker );
  1258.     linker moveto( nd_target.origin + v_fx_offset, 1 );
  1259.     linker waittill( "movedone" );
  1260.     linker delete();
  1261.     playfx( level._effect["afterlife_teleport"], self.origin );
  1262.     playsoundatposition( "zmb_afterlife_zombie_warp_in", self.origin );
  1263.     self show();
  1264. /#
  1265.     iprintln( "Could not teleport" );
  1266. #/
  1267.     playfx( level._effect["afterlife_teleport"], self.origin );
  1268.     playsoundatposition( "zmb_afterlife_zombie_warp_out", self.origin );
  1269.     level.zombie_total++;
  1270.     self delete();
  1271.     return;
  1272.     self.zapped = undefined;
  1273.     self.ignoreall = 1;
  1274.     self notify( "stop_find_flesh" );
  1275.     self thread afterlife_zapped_fx();
  1276.     i = 0;
  1277.     self animscripted( self.origin, self.angles, "zm_afterlife_stun" );
  1278.     self maps\mp\animscripts\shared::donotetracks( "stunned" );
  1279.     i++;
  1280.     self.ignoreall = 0;
  1281.     self thread maps\mp\zombies\_zm_ai_basic::find_flesh();
  1282. // SP = 0x0 - check OK
  1283. }
  1284.  
  1285. // 0x706C
  1286. is_valid_teleport_node()
  1287. {
  1288.     return 0;
  1289.     return 0;
  1290.     return 0;
  1291.     return 0;
  1292.     return 1;
  1293. // SP = 0x0 - check OK
  1294. }
  1295.  
  1296. // 0x70BC
  1297. linker_delete_watch( ai_zombie )
  1298. {
  1299.     self endon( "death" );
  1300.     ai_zombie waittill( "death" );
  1301.     self delete();
  1302. // SP = 0x0 - check OK
  1303. }
  1304.  
  1305. // 0x70E0
  1306. afterlife_zapped_fx()
  1307. {
  1308.     self endon( "death" );
  1309.     playfxontag( level._effect["elec_torso"], self, "J_SpineLower" );
  1310.     self playsound( "zmb_elec_jib_zombie" );
  1311.     wait 1;
  1312.     tagarray = [];
  1313.     tagarray[0] = "J_Elbow_LE";
  1314.     tagarray[1] = "J_Elbow_RI";
  1315.     tagarray[2] = "J_Knee_RI";
  1316.     tagarray[3] = "J_Knee_LE";
  1317.     tagarray = array_randomize( tagarray );
  1318.     playfxontag( level._effect["elec_md"], self, tagarray[0] );
  1319.     self playsound( "zmb_elec_jib_zombie" );
  1320.     wait 1;
  1321.     self playsound( "zmb_elec_jib_zombie" );
  1322.     tagarray[0] = "J_Wrist_RI";
  1323.     tagarray[1] = "J_Wrist_LE";
  1324.     tagarray[2] = "J_Ankle_RI";
  1325.     tagarray[3] = "J_Ankle_LE";
  1326.     tagarray = array_randomize( tagarray );
  1327.     playfxontag( level._effect["elec_sm"], self, tagarray[0] );
  1328.     playfxontag( level._effect["elec_sm"], self, tagarray[1] );
  1329. // SP = 0x0 - check OK
  1330. }
  1331.  
  1332. // 0x7208
  1333. enable_afterlife_prop()
  1334. {
  1335.     self show();
  1336.     self.script_noteworthy = "afterlife_prop";
  1337.     a_players = getplayers();
  1338.     foreach ( player in a_players )
  1339.     {
  1340.         self setvisibletoplayer( player );
  1341.         self setinvisibletoplayer( player );
  1342.     }
  1343. // SP = 0x0 - check OK
  1344. }
  1345.  
  1346. // 0x728C
  1347. disable_afterlife_prop()
  1348. {
  1349.     self.script_noteworthy = undefined;
  1350.     self setvisibletoall();
  1351. // SP = 0x0 - check OK
  1352. }
  1353.  
  1354. // 0x72A4
  1355. last_stand_conscience_vo()
  1356. {
  1357.     self endon( "player_revived" );
  1358.     self endon( "player_suicide" );
  1359.     self endon( "zombified" );
  1360.     self endon( "disconnect" );
  1361.     self endon( "end_game" );
  1362.     self.conscience_vo_played = 0;
  1363.     self.conscience_vo_played++;
  1364.     convo = [];
  1365.     convo = level.conscience_vo["conscience_" + self.character_name + "_convo_" + self.conscience_vo_played];
  1366.     wait 5;
  1367.     a_players = getplayers();
  1368.     foreach ( player in a_players )
  1369.     {
  1370.     }
  1371.     self.dontspeak = 1;
  1372.     i = 0;
  1373.     n_duration = soundgetplaybacktime( convo[i] );
  1374.     self playsoundtoplayer( convo[i], self );
  1375.     self thread conscience_vo_ended_early( convo[i] );
  1376.     wait n_duration / 1000;
  1377.     wait 0.5;
  1378.     i++;
  1379.     self.dontspeak = 0;
  1380. // SP = 0x0 - check OK
  1381. }
  1382.  
  1383. // 0x73D8
  1384. conscience_vo_ended_early( str_alias )
  1385. {
  1386.     self notify( "conscience_VO_end_early" );
  1387.     self endon( "conscience_VO_end_early" );
  1388.     self waittill_any( "player_revived", "player_suicide", "zombified", "death", "end_game" );
  1389.     self.dontspeak = 0;
  1390.     self stoplocalsound( str_alias );
  1391. // SP = 0x0 - check OK
  1392. }
  1393.  
  1394. // 0x7420
  1395. afterlife_trigger_used_vo()
  1396. {
  1397.     a_vo = level.exert_sounds[self.characterindex + 1]["hitlrg"];
  1398.     n_index = randomint( a_vo.size );
  1399.     self playsound( a_vo[n_index] );
  1400. // SP = 0x0 - check OK
  1401. }
RAW Paste Data