FineNerds

Sliquifier

Dec 28th, 2014
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.44 KB | None | 0 0
  1. #include maps/mp/zombies/_zm_audio;
  2. #include maps/mp/zombies/_zm_powerups;
  3. #include maps/mp/zombies/_zm_ai_basic;
  4. #include maps/mp/animscripts/zm_shared;
  5. #include maps/mp/animscripts/zm_utility;
  6. #include maps/mp/zombies/_zm;
  7. #include maps/mp/zombies/_zm_spawner;
  8. #include maps/mp/gametypes_zm/_weaponobjects;
  9. #include maps/mp/zombies/_zm_equipment;
  10. #include maps/mp/zombies/_zm_weapons;
  11. #include maps/mp/zombies/_zm_utility;
  12. #include maps/mp/_utility;
  13. #include common_scripts/utility;
  14.  
  15. set_zombie_var_once( var, value, is_float, column, is_team_based )
  16. {
  17.     if ( !isDefined( level.zombie_vars ) || !isDefined( level.zombie_vars[ var ] ) )
  18.     {
  19.         set_zombie_var( var, value, is_float, column, is_team_based );
  20.     }
  21. }
  22.  
  23. init()
  24. {
  25.     if ( !maps/mp/zombies/_zm_weapons::is_weapon_included( "slipgun_zm" ) )
  26.     {
  27.         return;
  28.     }
  29.     precachemodel( "t5_weapon_crossbow_bolt" );
  30.     precacheitem( "slip_bolt_zm" );
  31.     precacheitem( "slip_bolt_upgraded_zm" );
  32.     if ( is_true( level.slipgun_as_equipment ) )
  33.     {
  34.         maps/mp/zombies/_zm_equipment::register_equipment( "slipgun_zm", &"ZM_HIGHRISE_EQUIP_SLIPGUN_PICKUP_HINT_STRING", &"ZM_HIGHRISE_EQUIP_SLIPGUN_HOWTO", "jetgun_zm_icon", "slipgun", ::slipgun_activation_watcher_thread, ::transferslipgun, ::dropslipgun, ::pickupslipgun );
  35.         maps/mp/zombies/_zm_equipment::enemies_ignore_equipment( "slipgun_zm" );
  36.         maps/mp/gametypes_zm/_weaponobjects::createretrievablehint( "slipgun", &"ZM_HIGHRISE_EQUIP_SLIPGUN_PICKUP_HINT_STRING" );
  37.     }
  38.     set_zombie_var_once( "slipgun_reslip_max_spots", 8 );
  39.     set_zombie_var_once( "slipgun_reslip_rate", 6 );
  40.     set_zombie_var_once( "slipgun_max_kill_chain_depth", 16 );
  41.     set_zombie_var_once( "slipgun_max_kill_round", 100 );
  42.     set_zombie_var_once( "slipgun_chain_radius", 120 );
  43.     set_zombie_var_once( "slipgun_chain_wait_min", 0,75, 1 );
  44.     set_zombie_var_once( "slipgun_chain_wait_max", 1,5, 1 );
  45.     level.slippery_spot_count = 0;
  46.     level.sliquifier_distance_checks = 0;
  47.     maps/mp/zombies/_zm_spawner::register_zombie_damage_callback( ::slipgun_zombie_damage_response );
  48.     maps/mp/zombies/_zm_spawner::register_zombie_death_animscript_callback( ::slipgun_zombie_death_response );
  49.     level._effect[ "slipgun_explode" ] = loadfx( "weapon/liquifier/fx_liquifier_goo_explo" );
  50.     level._effect[ "slipgun_splatter" ] = loadfx( "maps/zombie/fx_zmb_goo_splat" );
  51.     level._effect[ "slipgun_simmer" ] = loadfx( "weapon/liquifier/fx_liquifier_goo_sizzle" );
  52.     level._effect[ "slipgun_viewmodel_eject" ] = loadfx( "weapon/liquifier/fx_liquifier_clip_eject" );
  53.     level._effect[ "slipgun_viewmodel_reload" ] = loadfx( "weapon/liquifier/fx_liquifier_reload_steam" );
  54.     onplayerconnect_callback( ::slipgun_player_connect );
  55.     thread wait_init_damage();
  56. }
  57.  
  58. wait_init_damage()
  59. {
  60.     while ( !isDefined( level.zombie_vars ) || !isDefined( level.zombie_vars[ "zombie_health_start" ] ) )
  61.     {
  62.         wait 1;
  63.     }
  64.     wait 1;
  65.     level.slipgun_damage = maps/mp/zombies/_zm::ai_zombie_health( level.zombie_vars[ "slipgun_max_kill_round" ] );
  66.     level.slipgun_damage_mod = "MOD_PROJECTILE_SPLASH";
  67. }
  68.  
  69. slipgun_player_connect()
  70. {
  71.     self thread watch_for_slip_bolt();
  72. }
  73.  
  74. watch_for_slip_bolt()
  75. {
  76.     self endon( "death" );
  77.     self endon( "disconnect" );
  78.     for ( ;; )
  79.     {
  80.         self waittill( "grenade_fire", grenade, weaponname, parent );
  81.         self.num_sliquifier_kills = 0;
  82.         switch( weaponname )
  83.         {
  84.             case "slip_bolt_zm":
  85.                 grenade thread slip_bolt( self, 0 );
  86.                 break;
  87.             continue;
  88.             case "slip_bolt_upgraded_zm":
  89.                 grenade thread slip_bolt( self, 1 );
  90.                 break;
  91.             continue;
  92.         }
  93.     }
  94. }
  95.  
  96. slip_bolt( player, upgraded )
  97. {
  98.     startpos = player getweaponmuzzlepoint();
  99.     self waittill( "explode", position );
  100.     duration = 24;
  101.     if ( upgraded )
  102.     {
  103.         duration = 36;
  104.     }
  105.     thread add_slippery_spot( position, duration, startpos );
  106. }
  107.  
  108. dropslipgun()
  109. {
  110.     item = self maps/mp/zombies/_zm_equipment::placed_equipment_think( "t6_wpn_zmb_slipgun_world", "slipgun_zm", self.origin + vectorScale( ( 0, 0, 1 ), 30 ), self.angles );
  111.     if ( isDefined( item ) )
  112.     {
  113.         item.original_owner = self;
  114.         item.owner = undefined;
  115.         item.name = "slipgun_zm";
  116.         item.requires_pickup = 1;
  117.         item.clipammo = self getweaponammoclip( item.name );
  118.         item.stockammo = self getweaponammostock( item.name );
  119.     }
  120.     self takeweapon( "slipgun_zm" );
  121.     return item;
  122. }
  123.  
  124. pickupslipgun( item )
  125. {
  126.     item.owner = self;
  127.     self giveweapon( item.name );
  128.     if ( isDefined( item.clipammo ) && isDefined( item.stockammo ) )
  129.     {
  130.         self setweaponammoclip( item.name, item.clipammo );
  131.         self setweaponammostock( item.name, item.stockammo );
  132.         item.clipammo = undefined;
  133.         item.stockammo = undefined;
  134.     }
  135. }
  136.  
  137. transferslipgun( fromplayer, toplayer )
  138. {
  139.     toplayer notify( "slipgun_zm_taken" );
  140.     fromplayer notify( "slipgun_zm_taken" );
  141. }
  142.  
  143. slipgun_activation_watcher_thread()
  144. {
  145.     self endon( "zombified" );
  146.     self endon( "disconnect" );
  147.     self endon( "slipgun_zm_taken" );
  148.     while ( 1 )
  149.     {
  150.         self waittill_either( "slipgun_zm_activate", "slipgun_zm_deactivate" );
  151.     }
  152. }
  153.  
  154. slipgun_debug_circle( origin, radius, seconds, onslope, parent, start )
  155. {
  156. /#
  157.     if ( getDvarInt( #"6136A815" ) )
  158.     {
  159.         frames = int( 20 * seconds );
  160.         if ( isDefined( parent ) )
  161.         {
  162.             time = seconds;
  163.             frames = 1;
  164.             while ( time > 0 )
  165.             {
  166.                 morigin = origin + ( parent.origin - start );
  167.                 if ( isDefined( onslope ) && onslope )
  168.                 {
  169.                     circle( morigin, radius, ( 0, 0, 1 ), 0, 1, frames );
  170.                 }
  171.                 else
  172.                 {
  173.                     circle( morigin, radius, ( 0, 0, 1 ), 0, 1, frames );
  174.                 }
  175.                 time -= 0,05;
  176.                 wait 0,05;
  177.             }
  178.         }
  179.         else if ( isDefined( onslope ) && onslope )
  180.         {
  181.             circle( origin, radius, ( 0, 0, 1 ), 0, 1, frames );
  182.             return;
  183.         }
  184.         else
  185.         {
  186.             circle( origin, radius, ( 0, 0, 1 ), 0, 1, frames );
  187. #/
  188.         }
  189.     }
  190. }
  191.  
  192. slipgun_debug_line( start, end, color, seconds )
  193. {
  194. /#
  195.     if ( getDvarInt( #"6136A815" ) )
  196.     {
  197.         frames = int( 20 * seconds );
  198.         line( start, end, color, 1, 0, frames );
  199. #/
  200.     }
  201. }
  202.  
  203. canzombieongoofall()
  204. {
  205.     if ( is_true( self.is_inert ) )
  206.     {
  207.         return 0;
  208.     }
  209.     if ( is_true( self.is_traversing ) )
  210.     {
  211.         return 0;
  212.     }
  213.     if ( is_true( self.barricade_enter ) )
  214.     {
  215.         return 0;
  216.     }
  217.     if ( randomint( 100 ) < 20 )
  218.     {
  219.         trace = groundtrace( self.origin + vectorScale( ( 0, 0, 1 ), 5 ), self.origin + vectorScale( ( 0, 0, 1 ), 300 ), 0, undefined );
  220.         origin = trace[ "position" ];
  221.         groundnormal = trace[ "normal" ];
  222.         if ( distancesquared( self.origin, origin ) > 256 )
  223.         {
  224.             return 0;
  225.         }
  226.         dot = vectordot( ( 0, 0, 1 ), groundnormal );
  227.         if ( dot < 0,9 )
  228.         {
  229.             return 0;
  230.         }
  231.         trace_origin = self.origin + vectorScale( anglesToForward( self.angles ), 200 );
  232.         trace = groundtrace( trace_origin + vectorScale( ( 0, 0, 1 ), 5 ), self.origin + vectorScale( ( 0, 0, 1 ), 300 ), 0, undefined );
  233.         origin = trace[ "position" ];
  234.         groundnormal = trace[ "normal" ];
  235.         if ( distancesquared( trace_origin, origin ) > 256 )
  236.         {
  237.             return 0;
  238.         }
  239.         dot = vectordot( ( 0, 0, 1 ), groundnormal );
  240.         if ( dot < 0,9 )
  241.         {
  242.             return 0;
  243.         }
  244.         return 1;
  245.     }
  246.     return 0;
  247. }
  248.  
  249. zombiemoveongoo()
  250. {
  251.     self endon( "death" );
  252.     self endon( "removed" );
  253.     level endon( "intermission" );
  254.     if ( is_true( self.sliding_on_goo ) )
  255.     {
  256.         return;
  257.     }
  258.     self notify( "endOnGoo" );
  259.     self endon( "endOnGoo" );
  260.     self notify( "stop_zombie_goto_entrance" );
  261.     self notify( "stop_find_flesh" );
  262.     self notify( "zombie_acquire_enemy" );
  263.     self.goo_last_vel = self getvelocity();
  264.     self.goo_last_pos = self.origin;
  265.     slide_direction = anglesToForward( self.angles );
  266.     self animmode( "slide" );
  267.     self orientmode( "face enemy" );
  268.     self.forcemovementscriptstate = 1;
  269.     self.ai_state = "zombieMoveOnGoo";
  270.     self maps/mp/zombies/_zm_spawner::zombie_history( "zombieMoveOnGoo " + getTime() );
  271.     self.sliding_on_goo = 0;
  272.     self thread zombiemoveongoo_on_killanimscript();
  273.     for ( ;; )
  274.     {
  275.         while ( 1 )
  276.         {
  277.             if ( isDefined( self.is_on_goo ) )
  278.             {
  279.                 self_on_goo = self.is_on_goo;
  280.             }
  281.             velocity = self getvelocity();
  282.             velocitylength = length( self getvelocity() );
  283.             if ( isDefined( self.has_legs ) )
  284.             {
  285.                 iscrawler = !self.has_legs;
  286.             }
  287.             isleaper = self is_leaper();
  288.             while ( is_true( self.is_leaping ) )
  289.             {
  290.                 wait 0,1;
  291.             }
  292.             if ( !self_on_goo )
  293.             {
  294.                 self animcustom( ::zombie_moveongoo_animcustom_recover );
  295.                 self waittill( "zombie_MoveOnGoo_animCustom_recover_done" );
  296.                 break;
  297.             }
  298.             else
  299.             {
  300.                 if ( velocitylength <= 0,2 )
  301.                 {
  302.                     self animmode( "normal" );
  303.                     wait 0,1;
  304.                     self animmode( "slide" );
  305.                 }
  306.                 if ( !self.sliding_on_goo || !issubstr( self.zombie_move_speed, "slide" ) )
  307.                 {
  308.                     if ( !iscrawler && !isleaper && !isDefined( self.fell_while_sliding ) && canzombieongoofall() )
  309.                     {
  310.                         self animcustom( ::zombie_moveongoo_animcustom_fall );
  311.                         self waittill( "zombie_MoveOnGoo_animCustom_fall_done" );
  312.                     }
  313.                 }
  314.                 else self.sliding_on_goo = 1;
  315.                 if ( velocitylength <= 0,2 )
  316.                 {
  317.                     wait 0,1;
  318.                 }
  319.                 self animmode( "slide" );
  320.                 self orientmode( "face enemy" );
  321.                 if ( self.zombie_move_speed == "sprint" )
  322.                 {
  323.                     if ( !isDefined( self.zombie_move_speed ) || isDefined( self.zombie_move_speed ) && self.zombie_move_speed != "sprint_slide" )
  324.                     {
  325.                         animstatedef = self maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "sprint_slide" );
  326.                         self set_zombie_run_cycle( animstatedef );
  327.                     }
  328.                     break;
  329.                 }
  330.                 else if ( self.zombie_move_speed == "run" )
  331.                 {
  332.                     if ( !isDefined( self.zombie_move_speed ) || isDefined( self.zombie_move_speed ) && self.zombie_move_speed != "run_slide" )
  333.                     {
  334.                         animstatedef = self maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "run_slide" );
  335.                         self set_zombie_run_cycle( animstatedef );
  336.                     }
  337.                     break;
  338.                 }
  339.                 else
  340.                 {
  341.                     if ( !isDefined( self.zombie_move_speed ) || isDefined( self.zombie_move_speed ) && self.zombie_move_speed != "walk_slide" )
  342.                     {
  343.                         animstatedef = self maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "walk_slide" );
  344.                         self set_zombie_run_cycle( animstatedef );
  345.                     }
  346.                 }
  347.             }
  348.             wait 0,05;
  349.         }
  350.     }
  351.     zombiemoveongoo_gobacktonormal();
  352. }
  353.  
  354. zombie_moveongoo_animcustom_fall()
  355. {
  356.     self endon( "death" );
  357.     self endon( "removed" );
  358.     level endon( "intermission" );
  359.     self.fell_while_sliding = 1;
  360.     self animmode( "normal" );
  361.     self orientmode( "face angle", self.angles[ 1 ] );
  362.     fallanimstatedef = "zm_move_slide_fall";
  363.     self setanimstatefromasd( fallanimstatedef );
  364.     maps/mp/animscripts/zm_shared::donotetracks( "slide_fall_anim" );
  365.     self notify( "zombie_MoveOnGoo_animCustom_fall_done" );
  366. }
  367.  
  368. zombie_moveongoo_animcustom_recover()
  369. {
  370.     self endon( "death" );
  371.     self endon( "removed" );
  372.     level endon( "intermission" );
  373.     self.recovering_from_goo = 1;
  374.     if ( randomint( 100 ) < 50 )
  375.     {
  376.         animstatedef = maps/mp/animscripts/zm_utility::append_missing_legs_suffix( "zm_move_slide_recover" );
  377.         self setanimstatefromasd( animstatedef );
  378.         maps/mp/animscripts/zm_shared::donotetracks( "slide_recover_anim" );
  379.     }
  380.     self.recovering_from_goo = 0;
  381.     zombiemoveongoo_gobacktonormal();
  382.     self notify( "zombie_MoveOnGoo_animCustom_recover_done" );
  383. }
  384.  
  385. zombiemoveongoo_on_killanimscript()
  386. {
  387.     self endon( "death" );
  388.     self endon( "removed" );
  389.     level endon( "intermission" );
  390.     self notify( "zombieMoveOnGoo_on_killAnimScript_thread" );
  391.     self endon( "zombieMoveOnGoo_on_killAnimScript_thread" );
  392.     self waittill_any( "endOnGoo", "killanimscript" );
  393.     zombiemoveongoo_gobacktonormal();
  394. }
  395.  
  396. zombiemoveongoo_gobacktonormal()
  397. {
  398.     self animmode( "normal" );
  399.     self set_zombie_run_cycle();
  400.     self.sliding_on_goo = 0;
  401.     self.fell_while_sliding = undefined;
  402.     self notify( "zombieMoveOnGoo_on_killAnimScript_thread" );
  403.     self notify( "endOnGoo" );
  404.     self.forcemovementscriptstate = 0;
  405.     if ( !is_true( self.completed_emerging_into_playable_area ) )
  406.     {
  407. /#
  408.         assert( isDefined( self.first_node ) );
  409. #/
  410.         self maps/mp/zombies/_zm_spawner::reset_attack_spot();
  411.         self orientmode( "face default" );
  412.         self thread maps/mp/zombies/_zm_spawner::zombie_goto_entrance( self.first_node );
  413.     }
  414.     else
  415.     {
  416.         self orientmode( "face enemy" );
  417.         self thread maps/mp/zombies/_zm_ai_basic::find_flesh();
  418.     }
  419. }
  420.  
  421. zombie_can_slip()
  422. {
  423.     if ( is_true( self.barricade_enter ) )
  424.     {
  425.         return 0;
  426.     }
  427.     if ( is_true( self.is_traversing ) )
  428.     {
  429.         return 0;
  430.     }
  431.     if ( !is_true( self.completed_emerging_into_playable_area ) && !isDefined( self.first_node ) )
  432.     {
  433.         return 0;
  434.     }
  435.     if ( is_true( self.is_leaping ) )
  436.     {
  437.         return 0;
  438.     }
  439.     return 1;
  440. }
  441.  
  442. zombie_set_slipping( onoff )
  443. {
  444.     if ( isDefined( self ) )
  445.     {
  446.         self.is_on_goo = onoff;
  447.         if ( onoff )
  448.         {
  449.             self thread zombiemoveongoo();
  450.         }
  451.     }
  452. }
  453.  
  454. slippery_spot_choke( lifetime )
  455. {
  456.     level.sliquifier_distance_checks++;
  457.     if ( level.sliquifier_distance_checks >= 32 )
  458.     {
  459.         level.sliquifier_distance_checks = 0;
  460.         lifetime -= 0,05;
  461.         wait 0,05;
  462.     }
  463.     return lifetime;
  464. }
  465.  
  466. add_slippery_spot( origin, duration, startpos )
  467. {
  468.     wait 0,5;
  469.     level.slippery_spot_count++;
  470.     hit_norm = vectornormalize( startpos - origin );
  471.     hit_from = 6 * hit_norm;
  472.     trace_height = 120;
  473.     trace = bullettrace( origin + hit_from, origin + hit_from + ( 0, 0, trace_height * -1 ), 0, undefined );
  474.     if ( isDefined( trace[ "entity" ] ) )
  475.     {
  476.         parent = trace[ "entity" ];
  477.         if ( is_true( parent.can_move ) )
  478.         {
  479.             return;
  480.         }
  481.     }
  482.     fxorigin = origin + hit_from;
  483. /#
  484.     red = ( 0, 0, 1 );
  485.     green = ( 0, 0, 1 );
  486.     dkgreen = vectorScale( ( 0, 0, 1 ), 0,15 );
  487.     blue = ( 0, 0, 1 );
  488.     grey = vectorScale( ( 0, 0, 1 ), 0,3 );
  489.     black = ( 0, 0, 1 );
  490.     slipgun_debug_line( origin, origin + hit_from, red, duration );
  491.     if ( trace[ "fraction" ] == 1 )
  492.     {
  493.         slipgun_debug_line( origin + hit_from, origin + hit_from + ( 0, 0, trace_height * -1 ), grey, duration );
  494.     }
  495.     else
  496.     {
  497.         slipgun_debug_line( origin + hit_from, trace[ "position" ], green, duration );
  498.         slipgun_debug_line( trace[ "position" ], origin + hit_from + ( 0, 0, trace_height * -1 ), dkgreen, duration );
  499. #/
  500.     }
  501.     if ( trace[ "fraction" ] == 1 )
  502.     {
  503.         return;
  504.     }
  505.     moving_parent = undefined;
  506.     moving_parent_start = ( 0, 0, 1 );
  507.     if ( isDefined( trace[ "entity" ] ) )
  508.     {
  509.         parent = trace[ "entity" ];
  510.         if ( is_true( parent.can_move ) )
  511.         {
  512.             return;
  513.         }
  514.     }
  515.     origin = trace[ "position" ];
  516.     thread pool_of_goo( fxorigin, duration );
  517.     if ( !isDefined( level.slippery_spots ) )
  518.     {
  519.         level.slippery_spots = [];
  520.     }
  521.     level.slippery_spots[ level.slippery_spots.size ] = origin;
  522.     radius = 60;
  523.     height = 48;
  524. /#
  525.     thread slipgun_debug_circle( origin, radius, duration, 0, moving_parent, moving_parent_start );
  526. #/
  527.     slicked_players = [];
  528.     slicked_zombies = [];
  529.     lifetime = duration;
  530.     radius2 = radius * radius;
  531.     while ( lifetime > 0 )
  532.     {
  533.         oldlifetime = lifetime;
  534.         _a612 = get_players();
  535.         _k612 = getFirstArrayKey( _a612 );
  536.         while ( isDefined( _k612 ) )
  537.         {
  538.             player = _a612[ _k612 ];
  539.             num = player getentitynumber();
  540.             morigin = origin;
  541.             if ( isDefined( moving_parent ) )
  542.             {
  543.                 morigin = origin + ( moving_parent.origin - moving_parent_start );
  544.             }
  545.             if ( distance2dsquared( player.origin, morigin ) < radius2 )
  546.             {
  547.                 should_be_slick = abs( player.origin[ 2 ] - morigin[ 2 ] ) < height;
  548.             }
  549.             is_slick = isDefined( slicked_players[ num ] );
  550.             if ( should_be_slick != is_slick )
  551.             {
  552.                 if ( !isDefined( player.slick_count ) )
  553.                 {
  554.                     player.slick_count = 0;
  555.                 }
  556.                 if ( should_be_slick )
  557.                 {
  558.                     player.slick_count++;
  559.                     slicked_players[ num ] = player;
  560.                 }
  561.                 else
  562.                 {
  563.                     player.slick_count--;
  564.  
  565. /#
  566.                     assert( player.slick_count >= 0 );
  567. #/
  568.                 }
  569. /#
  570. #/
  571.                 player forceslick( player.slick_count );
  572.             }
  573.             lifetime = slippery_spot_choke( lifetime );
  574.             _k612 = getNextArrayKey( _a612, _k612 );
  575.         }
  576.         zombies = get_round_enemy_array();
  577.         while ( isDefined( zombies ) )
  578.         {
  579.             _a645 = zombies;
  580.             _k645 = getFirstArrayKey( _a645 );
  581.             while ( isDefined( _k645 ) )
  582.             {
  583.                 zombie = _a645[ _k645 ];
  584.                 if ( isDefined( zombie ) )
  585.                 {
  586.                     num = zombie getentitynumber();
  587.                     morigin = origin;
  588.                     if ( isDefined( moving_parent ) )
  589.                     {
  590.                         morigin = origin + ( moving_parent.origin - moving_parent_start );
  591.                     }
  592.                     if ( distance2dsquared( zombie.origin, morigin ) < radius2 )
  593.                     {
  594.                         should_be_slick = abs( zombie.origin[ 2 ] - morigin[ 2 ] ) < height;
  595.                     }
  596.                     if ( should_be_slick && !zombie zombie_can_slip() )
  597.                     {
  598.                         should_be_slick = 0;
  599.                     }
  600.                     is_slick = isDefined( slicked_zombies[ num ] );
  601.                     if ( should_be_slick != is_slick )
  602.                     {
  603.                         if ( !isDefined( zombie.slick_count ) )
  604.                         {
  605.                             zombie.slick_count = 0;
  606.                         }
  607.                         if ( should_be_slick )
  608.                         {
  609.                             zombie.slick_count++;
  610.                             slicked_zombies[ num ] = zombie;
  611.                         }
  612.                         else
  613.                         {
  614.                             if ( zombie.slick_count > 0 )
  615.                             {
  616.                                 zombie.slick_count--;
  617.  
  618.                             }
  619.                         }
  620.                         zombie zombie_set_slipping( zombie.slick_count > 0 );
  621.                     }
  622.                     lifetime = slippery_spot_choke( lifetime );
  623.                 }
  624.                 _k645 = getNextArrayKey( _a645, _k645 );
  625.             }
  626.         }
  627.         if ( oldlifetime == lifetime )
  628.         {
  629.             lifetime -= 0,05;
  630.             wait 0,05;
  631.         }
  632.     }
  633.     _a684 = slicked_players;
  634.     _k684 = getFirstArrayKey( _a684 );
  635.     while ( isDefined( _k684 ) )
  636.     {
  637.         player = _a684[ _k684 ];
  638.         player.slick_count--;
  639.  
  640. /#
  641.         assert( player.slick_count >= 0 );
  642. #/
  643.         player forceslick( player.slick_count );
  644.         _k684 = getNextArrayKey( _a684, _k684 );
  645.     }
  646.     _a690 = slicked_zombies;
  647.     _k690 = getFirstArrayKey( _a690 );
  648.     while ( isDefined( _k690 ) )
  649.     {
  650.         zombie = _a690[ _k690 ];
  651.         if ( isDefined( zombie ) )
  652.         {
  653.             if ( zombie.slick_count > 0 )
  654.             {
  655.                 zombie.slick_count--;
  656.  
  657.             }
  658.             zombie zombie_set_slipping( zombie.slick_count > 0 );
  659.         }
  660.         _k690 = getNextArrayKey( _a690, _k690 );
  661.     }
  662.     arrayremovevalue( level.slippery_spots, origin, 0 );
  663.     level.slippery_spot_count--;
  664.  
  665. }
  666.  
  667. pool_of_goo( origin, duration )
  668. {
  669.     effect_life = 24;
  670.     if ( duration > effect_life )
  671.     {
  672.         pool_of_goo( origin, duration - effect_life );
  673.         duration = effect_life;
  674.     }
  675.     if ( isDefined( level._effect[ "slipgun_splatter" ] ) )
  676.     {
  677.         playfx( level._effect[ "slipgun_splatter" ], origin );
  678.     }
  679.     wait duration;
  680. }
  681.  
  682. explode_into_goo( player, chain_depth )
  683. {
  684.     if ( isDefined( self.marked_for_insta_upgraded_death ) )
  685.     {
  686.         return;
  687.     }
  688.     tag = "J_SpineLower";
  689.     if ( is_true( self.isdog ) )
  690.     {
  691.         tag = "tag_origin";
  692.     }
  693.     self.guts_explosion = 1;
  694.     self playsound( "wpn_slipgun_zombie_explode" );
  695.     if ( isDefined( level._effect[ "slipgun_explode" ] ) )
  696.     {
  697.         playfx( level._effect[ "slipgun_explode" ], self gettagorigin( tag ) );
  698.     }
  699.     if ( !is_true( self.isdog ) )
  700.     {
  701.         wait 0,1;
  702.     }
  703.     self ghost();
  704.     if ( !isDefined( self.goo_chain_depth ) )
  705.     {
  706.         self.goo_chain_depth = chain_depth;
  707.     }
  708.     chain_radius = level.zombie_vars[ "slipgun_chain_radius" ];
  709.     level thread explode_to_near_zombies( player, self.origin, chain_radius, self.goo_chain_depth );
  710. }
  711.  
  712. explode_to_near_zombies( player, origin, radius, chain_depth )
  713. {
  714.     if ( level.zombie_vars[ "slipgun_max_kill_chain_depth" ] > 0 && chain_depth > level.zombie_vars[ "slipgun_max_kill_chain_depth" ] )
  715.     {
  716.         return;
  717.     }
  718.     enemies = get_round_enemy_array();
  719.     enemies = get_array_of_closest( origin, enemies );
  720.     minchainwait = level.zombie_vars[ "slipgun_chain_wait_min" ];
  721.     maxchainwait = level.zombie_vars[ "slipgun_chain_wait_max" ];
  722.     rsquared = radius * radius;
  723.     tag = "J_Head";
  724.     marked_zombies = [];
  725.     while ( isDefined( enemies ) && enemies.size )
  726.     {
  727.         index = 0;
  728.         enemy = enemies[ index ];
  729.         while ( distancesquared( enemy.origin, origin ) < rsquared )
  730.         {
  731.             if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) && !isDefined( enemy.slipgun_sizzle ) )
  732.             {
  733.                 trace = bullettrace( origin + vectorScale( ( 0, 0, 1 ), 50 ), enemy.origin + vectorScale( ( 0, 0, 1 ), 50 ), 0, undefined, 1 );
  734.                 if ( isDefined( trace[ "fraction" ] ) && trace[ "fraction" ] == 1 )
  735.                 {
  736.                     enemy.slipgun_sizzle = playfxontag( level._effect[ "slipgun_simmer" ], enemy, tag );
  737.                     marked_zombies[ marked_zombies.size ] = enemy;
  738.                 }
  739.             }
  740.             index++;
  741.             if ( index >= enemies.size )
  742.             {
  743.                 break;
  744.             }
  745.             else
  746.             {
  747.                 enemy = enemies[ index ];
  748.             }
  749.         }
  750.     }
  751.     while ( isDefined( marked_zombies ) && marked_zombies.size )
  752.     {
  753.         _a799 = marked_zombies;
  754.         _k799 = getFirstArrayKey( _a799 );
  755.         while ( isDefined( _k799 ) )
  756.         {
  757.             enemy = _a799[ _k799 ];
  758.             if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) )
  759.             {
  760.                 wait randomfloatrange( minchainwait, maxchainwait );
  761.                 if ( isalive( enemy ) && !is_true( enemy.guts_explosion ) && !is_true( enemy.nuked ) )
  762.                 {
  763.                     if ( !isDefined( enemy.goo_chain_depth ) )
  764.                     {
  765.                         enemy.goo_chain_depth = chain_depth;
  766.                     }
  767.                     if ( enemy.health > 0 )
  768.                     {
  769.                         if ( player maps/mp/zombies/_zm_powerups::is_insta_kill_active() )
  770.                         {
  771.                             enemy.health = 1;
  772.                         }
  773.                         enemy dodamage( level.slipgun_damage, origin, player, player, "none", level.slipgun_damage_mod, 0, "slip_goo_zm" );
  774.                     }
  775.                     if ( level.slippery_spot_count < level.zombie_vars[ "slipgun_reslip_max_spots" ] )
  776.                     {
  777.                         if ( isDefined( enemy.slick_count ) && enemy.slick_count == 0 && enemy.health <= 0 )
  778.                         {
  779.                             if ( level.zombie_vars[ "slipgun_reslip_rate" ] > 0 && randomint( level.zombie_vars[ "slipgun_reslip_rate" ] ) == 0 )
  780.                             {
  781.                                 startpos = origin;
  782.                                 duration = 24;
  783.                                 thread add_slippery_spot( enemy.origin, duration, startpos );
  784.                             }
  785.                         }
  786.                     }
  787.                 }
  788.             }
  789.             _k799 = getNextArrayKey( _a799, _k799 );
  790.         }
  791.     }
  792. }
  793.  
  794. slipgun_zombie_1st_hit_response( upgraded, player )
  795. {
  796.     self notify( "stop_find_flesh" );
  797.     self notify( "zombie_acquire_enemy" );
  798.     self orientmode( "face default" );
  799.     self.ignoreall = 1;
  800.     self.gibbed = 1;
  801.     if ( isalive( self ) )
  802.     {
  803.         if ( !isDefined( self.goo_chain_depth ) )
  804.         {
  805.             self.goo_chain_depth = 0;
  806.         }
  807.         if ( self.health > 0 )
  808.         {
  809.             if ( player maps/mp/zombies/_zm_powerups::is_insta_kill_active() )
  810.             {
  811.                 self.health = 1;
  812.             }
  813.             self dodamage( level.slipgun_damage, self.origin, player, player, "none", level.slipgun_damage_mod, 0, "slip_goo_zm" );
  814.         }
  815.     }
  816. }
  817.  
  818. slipgun_zombie_hit_response_internal( mod, damageweapon, player )
  819. {
  820.     if ( !self is_slipgun_damage( mod, damageweapon ) && !is_slipgun_explosive_damage( mod, damageweapon ) )
  821.     {
  822.         return 0;
  823.     }
  824.     self playsound( "wpn_slipgun_zombie_impact" );
  825.     upgraded = damageweapon == "slipgun_upgraded_zm";
  826.     self thread slipgun_zombie_1st_hit_response( upgraded, player );
  827.     if ( isDefined( player ) && isplayer( player ) )
  828.     {
  829.         player thread slipgun_play_zombie_hit_vox();
  830.     }
  831.     return 1;
  832. }
  833.  
  834. slipgun_zombie_damage_response( mod, hit_location, hit_origin, player, amount )
  835. {
  836.     return slipgun_zombie_hit_response_internal( mod, self.damageweapon, player );
  837. }
  838.  
  839. slipgun_zombie_death_response()
  840. {
  841.     if ( !self is_slipgun_damage( self.damagemod, self.damageweapon ) && !is_slipgun_explosive_damage( self.damagemod, self.damageweapon ) )
  842.     {
  843.         return 0;
  844.     }
  845.     level maps/mp/zombies/_zm_spawner::zombie_death_points( self.origin, self.damagemod, self.damagelocation, self.attacker, self );
  846.     self explode_into_goo( self.attacker, 0 );
  847.     return 1;
  848. }
  849.  
  850. is_slipgun_explosive_damage( mod, weapon )
  851. {
  852.     if ( isDefined( weapon ) )
  853.     {
  854.         if ( weapon != "slip_goo_zm" && weapon != "slip_bolt_zm" )
  855.         {
  856.             return weapon == "slip_bolt_upgraded_zm";
  857.         }
  858.     }
  859. }
  860.  
  861. is_slipgun_damage( mod, weapon )
  862. {
  863.     if ( isDefined( weapon ) )
  864.     {
  865.         if ( weapon != "slipgun_zm" )
  866.         {
  867.             return weapon == "slipgun_upgraded_zm";
  868.         }
  869.     }
  870. }
  871.  
  872. slipgun_play_zombie_hit_vox()
  873. {
  874.     rand = randomintrange( 0, 101 );
  875.     if ( rand >= 20 )
  876.     {
  877.         self maps/mp/zombies/_zm_audio::create_and_play_dialog( "kill", "human" );
  878.     }
  879. }
Advertisement
Add Comment
Please, Sign In to add comment