burc_2004

_zm_weap_staff_air.gsc

Oct 22nd, 2015
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.10 KB | None | 0 0
  1. #include maps/mp/animscripts/shared;
  2. #include maps/mp/zombies/_zm_powerups;
  3. #include maps/mp/zombies/_zm_audio;
  4. #include maps/mp/zombies/_zm_spawner;
  5. #include maps/mp/zombies/_zm_ai_basic;
  6. #include maps/mp/zm_tomb_utility;
  7. #include maps/mp/zombies/_zm_net;
  8. #include maps/mp/zombies/_zm_utility;
  9. #include maps/mp/_utility;
  10. #include common_scripts/utility;
  11.  
  12. init()
  13. {
  14.     level._effect[ "whirlwind" ] = loadfx( "weapon/zmb_staff/fx_zmb_staff_air_ug_impact_miss" );
  15.     registerclientfield( "scriptmover", "whirlwind_play_fx", 14000, 1, "int" );
  16.     registerclientfield( "actor", "air_staff_launch", 14000, 1, "int" );
  17.     registerclientfield( "allplayers", "air_staff_source", 14000, 1, "int" );
  18.     onplayerconnect_callback( ::onplayerconnect );
  19.     maps/mp/zombies/_zm_ai_basic::init_inert_zombies();
  20.     flag_init( "whirlwind_active" );
  21.     maps/mp/zombies/_zm_spawner::register_zombie_damage_callback( ::staff_air_zombie_damage_response );
  22.     maps/mp/zombies/_zm_spawner::register_zombie_death_event_callback( ::staff_air_death_event );
  23. }
  24.  
  25. precache()
  26. {
  27.     precacheitem( "staff_air_melee_zm" );
  28. }
  29.  
  30. onplayerconnect()
  31. {
  32.     self thread onplayerspawned();
  33. }
  34.  
  35. onplayerspawned()
  36. {
  37.     self endon( "disconnect" );
  38.     self thread watch_staff_air_fired();
  39.     self thread watch_staff_air_impact();
  40.     self thread watch_staff_usage();
  41. }
  42.  
  43. air_projectile_delete()
  44. {
  45.     self endon( "death" );
  46.     wait 0,75;
  47.     self delete();
  48. }
  49.  
  50. watch_staff_air_fired()
  51. {
  52.     self endon( "disconnect" );
  53.     while ( 1 )
  54.     {
  55.         self waittill( "missile_fire", e_projectile, str_weapon );
  56.         if ( str_weapon == "staff_air_upgraded_zm" || str_weapon == "staff_air_zm" )
  57.         {
  58.             e_projectile thread air_projectile_delete();
  59.             wind_damage_cone( str_weapon );
  60.             self setclientfield( "air_staff_source", 1 );
  61.             wait_network_frame();
  62.             self setclientfield( "air_staff_source", 0 );
  63.         }
  64.     }
  65. }
  66.  
  67. watch_staff_air_impact()
  68. {
  69.     self endon( "disconnect" );
  70.     while ( 1 )
  71.     {
  72.         self waittill( "projectile_impact", str_weap_name, v_explode_point, n_radius, projectile );
  73.         if ( str_weap_name == "staff_air_upgraded2_zm" || str_weap_name == "staff_air_upgraded3_zm" )
  74.         {
  75.             self thread staff_air_find_source( v_explode_point, str_weap_name );
  76.         }
  77.     }
  78. }
  79.  
  80. staff_air_find_source( v_detonate, str_weapon )
  81. {
  82.     self endon( "disconnect" );
  83.     if ( !isDefined( v_detonate ) )
  84.     {
  85.         return;
  86.     }
  87.     a_zombies = getaiarray( level.zombie_team );
  88.     a_zombies = get_array_of_closest( v_detonate, a_zombies );
  89.     if ( a_zombies.size )
  90.     {
  91.         i = 0;
  92.         while ( i < a_zombies.size )
  93.         {
  94.             if ( isalive( a_zombies[ i ] ) )
  95.             {
  96.                 if ( is_true( a_zombies[ i ].staff_hit ) )
  97.                 {
  98.                     i++;
  99.                     continue;
  100.                 }
  101.                 else
  102.                 {
  103.                     if ( distance2dsquared( v_detonate, a_zombies[ i ].origin ) <= 10000 )
  104.                     {
  105.                         self thread staff_air_zombie_source( a_zombies[ 0 ], str_weapon );
  106.                     }
  107.                     else
  108.                     {
  109.                         self thread staff_air_position_source( v_detonate, str_weapon );
  110.                     }
  111.                     return;
  112.                 }
  113.             }
  114.             i++;
  115.         }
  116.     }
  117.     else self thread staff_air_position_source( v_detonate, str_weapon );
  118. }
  119.  
  120. staff_air_zombie_source( ai_zombie, str_weapon )
  121. {
  122.     self endon( "disconnect" );
  123.     ai_zombie.staff_hit = 1;
  124.     ai_zombie.is_source = 1;
  125.     v_whirlwind_pos = ai_zombie.origin;
  126.     self thread staff_air_position_source( v_whirlwind_pos, str_weapon );
  127.     if ( !isDefined( ai_zombie.is_mechz ) )
  128.     {
  129.         self thread source_zombie_death( ai_zombie );
  130.     }
  131. }
  132.  
  133. staff_air_position_source( v_detonate, str_weapon )
  134. {
  135.     self endon( "disconnect" );
  136.     if ( !isDefined( v_detonate ) )
  137.     {
  138.         return;
  139.     }
  140.     if ( flag( "whirlwind_active" ) )
  141.     {
  142.         level notify( "whirlwind_stopped" );
  143.         while ( flag( "whirlwind_active" ) )
  144.         {
  145.             wait_network_frame();
  146.         }
  147.         wait 0,3;
  148.     }
  149.     flag_set( "whirlwind_active" );
  150.     n_time = self.chargeshotlevel * 3,5;
  151.     e_whirlwind = spawn( "script_model", v_detonate + vectorScale( ( 0, 0, 0 ), 100 ) );
  152.     e_whirlwind setmodel( "tag_origin" );
  153.     e_whirlwind.angles = vectorScale( ( 0, 0, 0 ), 90 );
  154.     e_whirlwind thread puzzle_debug_position( "X", vectorScale( ( 0, 0, 0 ), 255 ) );
  155.     e_whirlwind moveto( groundpos_ignore_water_new( e_whirlwind.origin ), 0,05 );
  156.     e_whirlwind waittill( "movedone" );
  157.     e_whirlwind setclientfield( "whirlwind_play_fx", 1 );
  158.     e_whirlwind thread whirlwind_rumble_nearby_players( "whirlwind_active" );
  159.     e_whirlwind thread whirlwind_timeout( n_time );
  160.     wait 0,5;
  161.     e_whirlwind.player_owner = self;
  162.     e_whirlwind thread whirlwind_seek_zombies( self.chargeshotlevel, str_weapon );
  163. }
  164.  
  165. whirlwind_seek_zombies( n_level, str_weapon )
  166. {
  167.     self endon( "death" );
  168.     self.b_found_zombies = 0;
  169.     n_range = get_air_blast_range( n_level );
  170.     while ( 1 )
  171.     {
  172.         a_zombies = staff_air_zombie_range( self.origin, n_range );
  173.         if ( a_zombies.size )
  174.         {
  175.             self.b_found_zombies = 1;
  176.             self thread whirlwind_kill_zombies( n_level, str_weapon );
  177.             return;
  178.         }
  179.         else
  180.         {
  181.             wait 0,1;
  182.         }
  183.     }
  184. }
  185.  
  186. whirlwind_timeout( n_time )
  187. {
  188.     self endon( "death" );
  189.     level waittill_any_or_timeout( n_time, "whirlwind_stopped" );
  190.     level notify( "whirlwind_stopped" );
  191.     self setclientfield( "whirlwind_play_fx", 0 );
  192.     self notify( "stop_debug_position" );
  193.     flag_clear( "whirlwind_active" );
  194.     wait 1,5;
  195.     self delete();
  196. }
  197.  
  198. move_along_ground_position( v_position, n_time )
  199. {
  200.     v_diff = vectornormalize( v_position - self.origin );
  201.     v_newpos = self.origin + ( v_diff * 50 ) + vectorScale( ( 0, 0, 0 ), 50 );
  202.     v_ground = groundpos_ignore_water_new( v_newpos );
  203.     self moveto( v_ground, n_time );
  204. }
  205.  
  206. whirlwind_kill_zombies( n_level, str_weapon )
  207. {
  208.     self endon( "death" );
  209.     n_range = get_air_blast_range( n_level );
  210.     self.n_charge_level = n_level;
  211.     while ( 1 )
  212.     {
  213.         a_zombies = staff_air_zombie_range( self.origin, n_range );
  214.         a_zombies = get_array_of_closest( self.origin, a_zombies );
  215.         i = 0;
  216.         while ( i < a_zombies.size )
  217.         {
  218.             if ( !isDefined( a_zombies[ i ] ) )
  219.             {
  220.                 i++;
  221.                 continue;
  222.             }
  223.             else if ( a_zombies[ i ].ai_state != "find_flesh" )
  224.             {
  225.                 i++;
  226.                 continue;
  227.             }
  228.             else if ( is_true( a_zombies[ i ].is_mechz ) )
  229.             {
  230.                 i++;
  231.                 continue;
  232.             }
  233.             else if ( is_true( self._whirlwind_attract_anim ) )
  234.             {
  235.                 i++;
  236.                 continue;
  237.             }
  238.             else v_offset = ( 10, 10, 32 );
  239.             if ( !bullet_trace_throttled( self.origin + v_offset, a_zombies[ i ].origin + v_offset, undefined ) )
  240.             {
  241.                 i++;
  242.                 continue;
  243.             }
  244.             else if ( !isDefined( a_zombies[ i ] ) || !isalive( a_zombies[ i ] ) )
  245.             {
  246.                 i++;
  247.                 continue;
  248.             }
  249.             else
  250.             {
  251.                 v_offset = ( -10, -10, 64 );
  252.                 if ( !bullet_trace_throttled( self.origin + v_offset, a_zombies[ i ].origin + v_offset, undefined ) )
  253.                 {
  254.                     i++;
  255.                     continue;
  256.                 }
  257.                 else if ( !isDefined( a_zombies[ i ] ) || !isalive( a_zombies[ i ] ) )
  258.                 {
  259.                     i++;
  260.                     continue;
  261.                 }
  262.                 else
  263.                 {
  264.                     a_zombies[ i ] thread whirlwind_drag_zombie( self, str_weapon );
  265.                     wait 0,5;
  266.                 }
  267.             }
  268.             i++;
  269.         }
  270.         wait_network_frame();
  271.     }
  272. }
  273.  
  274. whirlwind_drag_zombie( e_whirlwind, str_weapon )
  275. {
  276.     if ( isDefined( self.e_linker ) )
  277.     {
  278.         return;
  279.     }
  280.     self whirlwind_move_zombie( e_whirlwind );
  281.     if ( isDefined( self ) && isDefined( e_whirlwind ) && flag( "whirlwind_active" ) )
  282.     {
  283.         player = e_whirlwind.player_owner;
  284.         self do_damage_network_safe( player, self.health, str_weapon, "MOD_IMPACT" );
  285.         level thread staff_air_gib( self );
  286.     }
  287. }
  288.  
  289. whirlwind_move_zombie( e_whirlwind )
  290. {
  291.     if ( isDefined( self.e_linker ) )
  292.     {
  293.         return;
  294.     }
  295.     self.e_linker = spawn( "script_origin", ( 0, 0, 0 ) );
  296.     self.e_linker.origin = self.origin;
  297.     self.e_linker.angles = self.angles;
  298.     self linkto( self.e_linker );
  299.     self thread whirlwind_unlink( e_whirlwind );
  300.     if ( isDefined( e_whirlwind ) )
  301.     {
  302.         n_dist_sq = distance2dsquared( e_whirlwind.origin, self.origin );
  303.     }
  304.     n_fling_range_sq = 900;
  305.     while ( isalive( self ) && n_dist_sq > n_fling_range_sq && isDefined( e_whirlwind ) && flag( "whirlwind_active" ) )
  306.     {
  307.         n_dist_sq = distance2dsquared( e_whirlwind.origin, self.origin );
  308.         if ( isDefined( self.ai_state ) && self.ai_state == "find_flesh" )
  309.         {
  310.             b_supercharged = e_whirlwind.n_charge_level == 3;
  311.             self thread whirlwind_attract_anim( e_whirlwind.origin, b_supercharged );
  312.             n_movetime = 1;
  313.             if ( b_supercharged )
  314.             {
  315.                 n_movetime = 0,8;
  316.             }
  317.             self.e_linker thread move_along_ground_position( e_whirlwind.origin, n_movetime );
  318.         }
  319.         else
  320.         {
  321.         }
  322.         wait 0,05;
  323.     }
  324.     self notify( "reached_whirlwind" );
  325.     self.e_linker delete();
  326. }
  327.  
  328. whirlwind_unlink( e_whirlwind )
  329. {
  330.     self endon( "death" );
  331.     e_whirlwind waittill( "death" );
  332.     self unlink();
  333. }
  334.  
  335. source_zombie_death( ai_zombie )
  336. {
  337.     self endon( "disconnect" );
  338.     n_range = get_air_blast_range( self.chargeshotlevel );
  339.     tag = "J_SpineUpper";
  340.     if ( ai_zombie.isdog )
  341.     {
  342.         tag = "J_Spine1";
  343.     }
  344.     v_source = ai_zombie gettagorigin( tag );
  345.     ai_zombie thread staff_air_fling_zombie( self );
  346.     a_zombies = staff_air_zombie_range( v_source, n_range );
  347.     if ( !isDefined( a_zombies ) )
  348.     {
  349.         return;
  350.     }
  351.     self thread staff_air_proximity_kill( a_zombies );
  352. }
  353.  
  354. get_air_blast_range( n_charge )
  355. {
  356.     switch( n_charge )
  357.     {
  358.         case 1:
  359.             n_range = 100;
  360.             break;
  361.         default:
  362.             n_range = 250;
  363.             break;
  364.     }
  365.     return n_range;
  366. }
  367.  
  368. staff_air_proximity_kill( a_zombies )
  369. {
  370.     self endon( "disconnect" );
  371.     if ( !isDefined( a_zombies ) )
  372.     {
  373.         return;
  374.     }
  375.     i = 0;
  376.     while ( i < a_zombies.size )
  377.     {
  378.         if ( isalive( a_zombies[ i ] ) )
  379.         {
  380.             a_zombies[ i ] thread staff_air_fling_zombie( self );
  381.             wait 0,05;
  382.         }
  383.         i++;
  384.     }
  385. }
  386.  
  387. staff_air_zombie_range( v_source, n_range )
  388. {
  389.     a_enemies = [];
  390.     a_zombies = getaiarray( level.zombie_team );
  391.     a_zombies = get_array_of_closest( v_source, a_zombies );
  392.     n_range_sq = n_range * n_range;
  393.     while ( isDefined( a_zombies ) )
  394.     {
  395.         i = 0;
  396.         while ( i < a_zombies.size )
  397.         {
  398.             if ( !isDefined( a_zombies[ i ] ) )
  399.             {
  400.                 i++;
  401.                 continue;
  402.             }
  403.             else v_zombie_pos = a_zombies[ i ].origin;
  404.             if ( isDefined( a_zombies[ i ].staff_hit ) && a_zombies[ i ].staff_hit == 1 )
  405.             {
  406.                 i++;
  407.                 continue;
  408.             }
  409.             else
  410.             {
  411.                 if ( distancesquared( v_source, v_zombie_pos ) > n_range_sq )
  412.                 {
  413.                     i++;
  414.                     continue;
  415.                 }
  416.                 else
  417.                 {
  418.                     a_enemies[ a_enemies.size ] = a_zombies[ i ];
  419.                 }
  420.             }
  421.             i++;
  422.         }
  423.     }
  424.     return a_enemies;
  425. }
  426.  
  427. staff_air_fling_zombie( player )
  428. {
  429.     player endon( "disconnect" );
  430.     if ( !isalive( self ) )
  431.     {
  432.         return;
  433.     }
  434.     if ( isDefined( self.is_source ) || cointoss() )
  435.     {
  436.         self thread zombie_launch( player, "staff_air_upgraded_zm" );
  437.     }
  438.     else
  439.     {
  440.         self do_damage_network_safe( player, self.health, "staff_air_upgraded_zm", "MOD_IMPACT" );
  441.         level thread staff_air_gib( self );
  442.     }
  443. }
  444.  
  445. zombie_launch( e_attacker, str_weapon )
  446. {
  447.     self do_damage_network_safe( e_attacker, self.health, str_weapon, "MOD_IMPACT" );
  448.     if ( isDefined( level.ragdoll_limit_check ) && !( [[ level.ragdoll_limit_check ]]() ) )
  449.     {
  450.         level thread staff_air_gib( self );
  451.     }
  452.     else
  453.     {
  454.         self startragdoll();
  455.         self setclientfield( "air_staff_launch", 1 );
  456.     }
  457. }
  458.  
  459. determine_launch_vector( e_attacker, ai_target )
  460. {
  461.     v_launch = ( vectornormalize( ai_target.origin - e_attacker.origin ) * randomintrange( 125, 150 ) ) + ( 0, 0, randomintrange( 75, 150 ) );
  462.     return v_launch;
  463. }
  464.  
  465. staff_air_gib( ai_zombie )
  466. {
  467.     if ( cointoss() )
  468.     {
  469.         ai_zombie thread zombie_gib_all();
  470.     }
  471.     ai_zombie thread zombie_gib_guts();
  472. }
  473.  
  474. staff_air_zombie_damage_response( mod, hit_location, hit_origin, player, amount )
  475. {
  476.     if ( self is_staff_air_damage() && mod != "MOD_MELEE" )
  477.     {
  478.         self thread stun_zombie();
  479.         return 1;
  480.     }
  481.     return 0;
  482. }
  483.  
  484. is_staff_air_damage()
  485. {
  486.     if ( isDefined( self.damageweapon ) && self.damageweapon != "staff_air_zm" && self.damageweapon == "staff_air_upgraded_zm" )
  487.     {
  488.         return !is_true( self.set_beacon_damage );
  489.     }
  490. }
  491.  
  492. staff_air_death_event()
  493. {
  494.     if ( is_staff_air_damage() && self.damagemod != "MOD_MELEE" )
  495.     {
  496.         if ( is_true( self.is_mechz ) )
  497.         {
  498.             return;
  499.         }
  500.         self thread maps/mp/zombies/_zm_audio::do_zombies_playvocals( "death", self.animname );
  501.         self thread zombie_eye_glow_stop();
  502.         if ( isDefined( level.ragdoll_limit_check ) && !( [[ level.ragdoll_limit_check ]]() ) )
  503.         {
  504.             level thread staff_air_gib( self );
  505.             return;
  506.         }
  507.         else
  508.         {
  509.             self startragdoll();
  510.             self setclientfield( "air_staff_launch", 1 );
  511.         }
  512.     }
  513. }
  514.  
  515. wind_damage_cone( str_weapon )
  516. {
  517.     fire_angles = self getplayerangles();
  518.     fire_origin = self getplayercamerapos();
  519.     a_targets = getaiarray( "axis" );
  520.     a_targets = get_array_of_closest( self.origin, a_targets, undefined, 12, 400 );
  521.     if ( str_weapon == "staff_air_upgraded_zm" )
  522.     {
  523.         n_damage = 3300;
  524.         n_fov = 60;
  525.     }
  526.     else
  527.     {
  528.         n_damage = 2050;
  529.         n_fov = 45;
  530.     }
  531.     _a675 = a_targets;
  532.     _k675 = getFirstArrayKey( _a675 );
  533.     while ( isDefined( _k675 ) )
  534.     {
  535.         target = _a675[ _k675 ];
  536.         if ( isai( target ) )
  537.         {
  538.             if ( within_fov( fire_origin, fire_angles, target gettagorigin( "j_spine4" ), cos( n_fov ) ) )
  539.             {
  540.                 if ( self maps/mp/zombies/_zm_powerups::is_insta_kill_active() )
  541.                 {
  542.                     n_damage = target.health;
  543.                 }
  544.                 target do_damage_network_safe( self, n_damage, str_weapon, "MOD_IMPACT" );
  545.             }
  546.         }
  547.         _k675 = getNextArrayKey( _a675, _k675 );
  548.     }
  549. }
  550.  
  551. stun_zombie()
  552. {
  553.     self endon( "death" );
  554.     if ( is_true( self.is_mechz ) )
  555.     {
  556.         return;
  557.     }
  558.     if ( is_true( self.is_electrocuted ) )
  559.     {
  560.         return;
  561.     }
  562.     if ( !isDefined( self.ai_state ) || self.ai_state != "find_flesh" )
  563.     {
  564.         return;
  565.     }
  566.     self.forcemovementscriptstate = 1;
  567.     self.ignoreall = 1;
  568.     self.is_electrocuted = 1;
  569.     tag = "J_SpineUpper";
  570.     if ( self.isdog )
  571.     {
  572.         tag = "J_Spine1";
  573.     }
  574.     self animscripted( self.origin, self.angles, "zm_electric_stun" );
  575.     self maps/mp/animscripts/shared::donotetracks( "stunned" );
  576.     self.forcemovementscriptstate = 0;
  577.     self.ignoreall = 0;
  578.     self.is_electrocuted = 0;
  579. }
  580.  
  581. whirlwind_attract_anim_watch_cancel()
  582. {
  583.     self endon( "death" );
  584.     while ( flag( "whirlwind_active" ) )
  585.     {
  586.         wait_network_frame();
  587.     }
  588.     self.deathanim = undefined;
  589.     self stopanimscripted();
  590.     self._whirlwind_attract_anim = 0;
  591. }
  592.  
  593. whirlwind_attract_anim( v_attract_point, b_move_fast )
  594. {
  595.     if ( !isDefined( b_move_fast ) )
  596.     {
  597.         b_move_fast = 0;
  598.     }
  599.     self endon( "death" );
  600.     level endon( "whirlwind_stopped" );
  601.     if ( is_true( self._whirlwind_attract_anim ) )
  602.     {
  603.         return;
  604.     }
  605.     v_angles_to_source = vectorToAngle( v_attract_point - self.origin );
  606.     v_source_to_target = vectorToAngle( self.origin - v_attract_point );
  607.     self.a.runblendtime = 0,9;
  608.     if ( self.has_legs )
  609.     {
  610.         self.needs_run_update = 1;
  611.         self._had_legs = 1;
  612.         if ( b_move_fast )
  613.         {
  614.             self animscripted( self.origin, v_source_to_target, "zm_move_whirlwind_fast" );
  615.         }
  616.         else
  617.         {
  618.             self animscripted( self.origin, v_source_to_target, "zm_move_whirlwind" );
  619.         }
  620.     }
  621.     else self.needs_run_update = 1;
  622.     self._had_legs = 0;
  623.     if ( b_move_fast )
  624.     {
  625.         self animscripted( self.origin, v_source_to_target, "zm_move_whirlwind_crawl" );
  626.     }
  627.     else
  628.     {
  629.         self animscripted( self.origin, v_source_to_target, "zm_move_whirlwind_fast_crawl" );
  630.     }
  631.     if ( is_true( self.nogravity ) )
  632.     {
  633.         self animmode( "none" );
  634.         self.nogravity = undefined;
  635.     }
  636.     self._whirlwind_attract_anim = 1;
  637.     self.a.runblendtime = self._normal_run_blend_time;
  638.     self thread whirlwind_attract_anim_watch_cancel();
  639.     self waittill( "reached_whirlwind" );
  640. }
Advertisement
Add Comment
Please, Sign In to add comment