burc_2004

_zm_transit_ai_screecher.gsc

Oct 21st, 2015
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 31.61 KB | None | 0 0
  1. #include maps/mp/zombies/_zm_stats;
  2. #include maps/mp/zombies/_zm_audio;
  3. #include maps/mp/zombies/_zm_laststand;
  4. #include maps/mp/gametypes_zm/_hud_util;
  5. #include maps/mp/zombies/_zm_spawner;
  6. #include maps/mp/animscripts/zm_shared;
  7. #include maps/mp/_visionset_mgr;
  8. #include maps/mp/zombies/_zm_ai_screecher;
  9. #include maps/mp/zombies/_zm_utility;
  10. #include maps/mp/_utility;
  11. #include common_scripts/utility;
  12.  
  13. precache()
  14. {
  15.     precacheshader( "fullscreen_claw_left" );
  16.     precacheshader( "fullscreen_claw_right" );
  17.     precacheshader( "fullscreen_claw_bottom" );
  18.     precachemodel( "p6_zm_screecher_hole" );
  19.     precachemodel( "fx_axis_createfx" );
  20.     precachestring( &"ZOMBIE_SCREECHER_ATTACH_FIRST" );
  21.     level._effect[ "screecher_spawn_a" ] = loadfx( "maps/zombie/fx_zmb_screech_hand_dirt_burst" );
  22.     level._effect[ "screecher_spawn_b" ] = loadfx( "maps/zombie/fx_zmb_screech_body_dirt_billowing" );
  23.     level._effect[ "screecher_spawn_c" ] = loadfx( "maps/zombie/fx_zmb_screech_body_dirt_falling" );
  24.     level._effect[ "screecher_hole" ] = loadfx( "maps/zombie/fx_zmb_screecher_hole" );
  25.     level._effect[ "screecher_vortex" ] = loadfx( "maps/zombie/fx_zmb_screecher_vortex" );
  26.     level._effect[ "screecher_death" ] = loadfx( "maps/zombie/fx_zmb_screech_death_ash" );
  27. }
  28.  
  29. init()
  30. {
  31.     level.screecher_spawners = getentarray( "screecher_zombie_spawner", "script_noteworthy" );
  32.     array_thread( level.screecher_spawners, ::add_spawn_function, ::screecher_prespawn );
  33.     level.zombie_ai_limit_screecher = 2;
  34.     level.zombie_screecher_count = 0;
  35.     if ( !isDefined( level.vsmgr_prio_overlay_zm_ai_screecher_blur ) )
  36.     {
  37.         level.vsmgr_prio_overlay_zm_ai_screecher_blur = 50;
  38.     }
  39.     maps/mp/_visionset_mgr::vsmgr_register_info( "overlay", "zm_ai_screecher_blur", 1, level.vsmgr_prio_overlay_zm_ai_screecher_blur, 1, 1, ::maps/mp/_visionset_mgr::vsmgr_timeout_lerp_thread_per_player, 0 );
  40.     level thread screecher_spawning_logic();
  41. /#
  42.     level thread screecher_debug();
  43. #/
  44.     registerclientfield( "actor", "render_third_person", 1, 1, "int" );
  45.     level.near_miss = 0;
  46. }
  47.  
  48. screecher_debug()
  49. {
  50. /#
  51. #/
  52. }
  53.  
  54. screecher_spawning_logic()
  55. {
  56.     level endon( "intermission" );
  57.     if ( level.intermission )
  58.     {
  59.         return;
  60.     }
  61. /#
  62.     if ( getDvarInt( "zombie_cheat" ) == 2 || getDvarInt( "zombie_cheat" ) >= 4 )
  63.     {
  64.         return;
  65. #/
  66.     }
  67.     if ( level.screecher_spawners.size < 1 )
  68.     {
  69. /#
  70.         assertmsg( "No active spawners in the map.  Check to see if the zone is active and if it's pointing to spawners." );
  71. #/
  72.         return;
  73.     }
  74.     while ( 1 )
  75.     {
  76.         while ( !isDefined( level.zombie_screecher_locations ) || level.zombie_screecher_locations.size <= 0 )
  77.         {
  78.             wait 0,1;
  79.         }
  80.         while ( level.zombie_screecher_count >= level.zombie_ai_limit_screecher )
  81.         {
  82.             wait 0,1;
  83.         }
  84.         while ( getDvarInt( #"B0C0D38F" ) )
  85.         {
  86.             wait 0,1;
  87.         }
  88.         if ( !flag( "spawn_zombies" ) )
  89.         {
  90.             flag_wait( "spawn_zombies" );
  91.         }
  92.         valid_players_in_screecher_zone = 0;
  93.         valid_players = [];
  94.         while ( valid_players_in_screecher_zone <= 0 )
  95.         {
  96.             players = getplayers();
  97.             valid_players_in_screecher_zone = 0;
  98.             p = 0;
  99.             while ( p < players.size )
  100.             {
  101.                 if ( is_player_valid( players[ p ] ) && player_in_screecher_zone( players[ p ] ) && !isDefined( players[ p ].screecher ) )
  102.                 {
  103.                     valid_players_in_screecher_zone++;
  104.                     valid_players[ valid_players.size ] = players[ p ];
  105.                 }
  106.                 p++;
  107.             }
  108.             if ( players.size == 1 )
  109.             {
  110.                 if ( is_player_valid( players[ 0 ] ) && !player_in_screecher_zone( players[ 0 ] ) )
  111.                 {
  112.                     level.spawn_delay = 1;
  113.                 }
  114.             }
  115.             wait 0,1;
  116.         }
  117.         if ( !isDefined( level.zombie_screecher_locations ) || level.zombie_screecher_locations.size <= 0 )
  118.         {
  119.             continue;
  120.         }
  121.         valid_players = array_randomize( valid_players );
  122.         player_left_zone = 0;
  123.         while ( isDefined( level.spawn_delay ) && level.spawn_delay )
  124.         {
  125. /#
  126.             screecher_print( "delay spawning 5 secs" );
  127. #/
  128.             spawn_points = get_array_of_closest( valid_players[ 0 ].origin, level.zombie_screecher_locations );
  129.             spawn_point = undefined;
  130.             if ( spawn_points.size >= 3 )
  131.             {
  132.                 spawn_point = spawn_points[ 2 ];
  133.             }
  134.             else if ( spawn_points.size >= 2 )
  135.             {
  136.                 spawn_point = spawn_points[ 1 ];
  137.             }
  138.             else
  139.             {
  140.                 if ( spawn_points.size >= 1 )
  141.                 {
  142.                     spawn_point = spawn_points[ 0 ];
  143.                 }
  144.             }
  145.             if ( isDefined( spawn_point ) )
  146.             {
  147.                 playsoundatposition( "zmb_vocals_screecher_spawn", spawn_point.origin );
  148.             }
  149.             delay_time = getTime() + 5000;
  150.             now_zone = getent( "screecher_spawn_now", "targetname" );
  151.             while ( getTime() < delay_time )
  152.             {
  153.                 in_zone = 0;
  154.                 if ( valid_players[ 0 ] istouching( now_zone ) )
  155.                 {
  156. /#
  157.                     screecher_print( "in now zone" );
  158. #/
  159.                     break;
  160.                 }
  161.                 else if ( !is_player_valid( valid_players[ 0 ] ) )
  162.                 {
  163.                     break;
  164.                 }
  165.                 else if ( player_in_screecher_zone( valid_players[ 0 ] ) )
  166.                 {
  167.                     in_zone = 1;
  168.                 }
  169.                 if ( !in_zone )
  170.                 {
  171.                     player_left_zone = 1;
  172.                     level.spawn_delay = 1;
  173.                     break;
  174.                 }
  175.                 else
  176.                 {
  177.                     wait 0,1;
  178.                 }
  179.             }
  180.         }
  181.         if ( isDefined( player_left_zone ) && player_left_zone )
  182.         {
  183.             continue;
  184.         }
  185.         level.spawn_delay = 0;
  186.         spawn_points = get_array_of_closest( valid_players[ 0 ].origin, level.zombie_screecher_locations );
  187.         spawn_point = undefined;
  188.         while ( !isDefined( spawn_points ) || spawn_points.size == 0 )
  189.         {
  190.             wait 0,1;
  191.         }
  192.         if ( !isDefined( level.last_spawn ) )
  193.         {
  194.             level.last_spawn_index = 0;
  195.             level.last_spawn = [];
  196.             level.last_spawn[ level.last_spawn_index ] = spawn_points[ 0 ];
  197.             level.last_spawn_index = 1;
  198.             spawn_point = spawn_points[ 0 ];
  199.         }
  200.         else _a250 = spawn_points;
  201.         _k250 = getFirstArrayKey( _a250 );
  202.         while ( isDefined( _k250 ) )
  203.         {
  204.             point = _a250[ _k250 ];
  205.             if ( point == level.last_spawn[ 0 ] )
  206.             {
  207.             }
  208.             else if ( isDefined( level.last_spawn[ 1 ] ) && point == level.last_spawn[ 1 ] )
  209.             {
  210.             }
  211.             else
  212.             {
  213.                 spawn_point = point;
  214.                 level.last_spawn[ level.last_spawn_index ] = spawn_point;
  215.                 level.last_spawn_index++;
  216.                 if ( level.last_spawn_index > 1 )
  217.                 {
  218.                     level.last_spawn_index = 0;
  219.                 }
  220.                 break;
  221.             }
  222.             _k250 = getNextArrayKey( _a250, _k250 );
  223.         }
  224.         if ( !isDefined( spawn_point ) )
  225.         {
  226.             spawn_point = spawn_points[ 0 ];
  227.         }
  228.         if ( isDefined( level.screecher_spawners ) )
  229.         {
  230.             spawner = random( level.screecher_spawners );
  231.             ai = spawn_zombie( spawner, spawner.targetname, spawn_point );
  232.         }
  233.         if ( isDefined( ai ) )
  234.         {
  235.             ai.spawn_point = spawn_point;
  236.             level.zombie_screecher_count++;
  237. /#
  238.             screecher_print( "screecher total " + level.zombie_screecher_count );
  239. #/
  240.         }
  241.         wait level.zombie_vars[ "zombie_spawn_delay" ];
  242.         wait 0,1;
  243.     }
  244. }
  245.  
  246. player_in_screecher_zone( player )
  247. {
  248.     if ( isDefined( level.is_player_in_screecher_zone ) )
  249.     {
  250.         infog = [[ level.is_player_in_screecher_zone ]]( player );
  251.         return infog;
  252.     }
  253.     return 1;
  254. }
  255.  
  256. screecher_should_runaway( player )
  257. {
  258.     players = get_players();
  259.     if ( players.size == 1 )
  260.     {
  261.         if ( level.near_miss == 1 )
  262.         {
  263.             level.near_miss = 2;
  264. /#
  265.             screecher_print( "runaway from near_miss " + level.near_miss );
  266. #/
  267.             return 1;
  268.         }
  269.     }
  270.     if ( isDefined( level.screecher_should_runaway ) )
  271.     {
  272.         return self [[ level.screecher_should_runaway ]]( player );
  273.     }
  274.     return 0;
  275. }
  276.  
  277. screecher_get_closest_valid_player( origin, ignore_player )
  278. {
  279.     valid_player_found = 0;
  280.     players = get_players();
  281.     if ( isDefined( level._zombie_using_humangun ) && level._zombie_using_humangun )
  282.     {
  283.         players = arraycombine( players, level._zombie_human_array, 0, 0 );
  284.     }
  285.     while ( isDefined( ignore_player ) )
  286.     {
  287.         i = 0;
  288.         while ( i < ignore_player.size )
  289.         {
  290.             arrayremovevalue( players, ignore_player[ i ] );
  291.             i++;
  292.         }
  293.     }
  294.     while ( !valid_player_found )
  295.     {
  296.         if ( isDefined( level.calc_closest_player_using_paths ) && level.calc_closest_player_using_paths )
  297.         {
  298.             player = get_closest_player_using_paths( origin, players );
  299.         }
  300.         else
  301.         {
  302.             player = getclosest( origin, players );
  303.         }
  304.         if ( !isDefined( player ) )
  305.         {
  306.             return undefined;
  307.         }
  308.         if ( isDefined( level._zombie_using_humangun ) && level._zombie_using_humangun && isai( player ) )
  309.         {
  310.             return player;
  311.         }
  312.         if ( isDefined( player.screecher ) )
  313.         {
  314.             screecher_claimed = player.screecher != self;
  315.         }
  316.         if ( players.size == 1 && screecher_claimed )
  317.         {
  318.             return undefined;
  319.         }
  320.         while ( is_player_valid( player, 1 ) || !player_in_screecher_zone( player ) && screecher_claimed )
  321.         {
  322.             arrayremovevalue( players, player );
  323.         }
  324.         return player;
  325.     }
  326. }
  327.  
  328. zombie_pathing_home()
  329. {
  330.     self endon( "death" );
  331.     self endon( "zombie_acquire_enemy" );
  332.     level endon( "intermission" );
  333.     self setgoalpos( self.startinglocation );
  334.     self waittill( "goal" );
  335.     playfx( level._effect[ "screecher_spawn_b" ], self.origin, ( 0, 0, 1 ) );
  336.     self.no_powerups = 1;
  337.     self setfreecameralockonallowed( 0 );
  338.     self animscripted( self.origin, self.angles, "zm_burrow" );
  339.     self playsound( "zmb_screecher_dig" );
  340.     maps/mp/animscripts/zm_shared::donotetracks( "burrow_anim" );
  341.     self delete();
  342. }
  343.  
  344. screecher_find_flesh()
  345. {
  346.     self endon( "death" );
  347.     level endon( "intermission" );
  348.     self endon( "stop_find_flesh" );
  349.     if ( level.intermission )
  350.     {
  351.         return;
  352.     }
  353.     self.helitarget = 1;
  354.     self.ignoreme = 0;
  355.     self.nododgemove = 1;
  356.     self.ignore_player = [];
  357.     self zombie_history( "find flesh -> start" );
  358.     self.goalradius = 32;
  359.     while ( 1 )
  360.     {
  361.         self.favoriteenemy = screecher_get_closest_valid_player( self.origin );
  362.         if ( isDefined( self.favoriteenemy ) )
  363.         {
  364.             self thread zombie_pathing();
  365.         }
  366.         else
  367.         {
  368.             self thread screecher_runaway();
  369.         }
  370.         self.zombie_path_timer = getTime() + ( randomfloatrange( 1, 3 ) * 1000 );
  371.         while ( getTime() < self.zombie_path_timer )
  372.         {
  373.             wait 0,1;
  374.         }
  375.         self notify( "path_timer_done" );
  376.         self zombie_history( "find flesh -> bottom of loop" );
  377.         debug_print( "Zombie is re-acquiring enemy, ending breadcrumb search" );
  378.         self notify( "zombie_acquire_enemy" );
  379.     }
  380. }
  381.  
  382. screecher_prespawn()
  383. {
  384.     self endon( "death" );
  385.     level endon( "intermission" );
  386.     self.startinglocation = self.origin;
  387.     self.animname = "screecher_zombie";
  388.     self.audio_type = "screecher";
  389.     self.has_legs = 1;
  390.     self.no_gib = 1;
  391.     self.isscreecher = 1;
  392.     self.ignore_enemy_count = 1;
  393.     recalc_zombie_array();
  394.     self.cant_melee = 1;
  395.     if ( isDefined( self.spawn_point ) )
  396.     {
  397.         spot = self.spawn_point;
  398.         if ( !isDefined( spot.angles ) )
  399.         {
  400.             spot.angles = ( 0, 0, 1 );
  401.         }
  402.         self forceteleport( spot.origin, spot.angles );
  403.     }
  404.     self set_zombie_run_cycle( "super_sprint" );
  405.     self setphysparams( 15, 0, 24 );
  406.     self.actor_damage_func = ::screecher_damage_func;
  407.     self.deathfunction = ::screecher_death_func;
  408.     self.zombie_init_done = 1;
  409.     self notify( "zombie_init_done" );
  410.     self.allowpain = 0;
  411.     self animmode( "normal" );
  412.     self orientmode( "face enemy" );
  413.     self.forcemovementscriptstate = 0;
  414.     self maps/mp/zombies/_zm_spawner::zombie_setup_attack_properties();
  415.     self maps/mp/zombies/_zm_spawner::zombie_complete_emerging_into_playable_area();
  416.     self setfreecameralockonallowed( 0 );
  417.     self.startinglocation = self.origin;
  418.     self playsound( "zmb_vocals_screecher_spawn" );
  419.     self thread play_screecher_fx();
  420.     self thread play_screecher_damaged_yelps();
  421.     self thread screecher_rise();
  422.     self thread screecher_cleanup();
  423.     self thread screecher_distance_tracking();
  424.     self.anchor = spawn( "script_origin", self.origin );
  425.     self.attack_time = 0;
  426.     self.attack_delay = 1000;
  427.     self.attack_delay_base = 1000;
  428.     self.attack_delay_offset = 500;
  429.     self.meleedamage = 5;
  430.     self.ignore_inert = 1;
  431.     self.player_score = 0;
  432.     self.screecher_score = 0;
  433.     if ( isDefined( level.screecher_init_done ) )
  434.     {
  435.         self thread [[ level.screecher_init_done ]]();
  436.     }
  437. }
  438.  
  439. play_screecher_fx()
  440. {
  441. /#
  442.     if ( isDefined( level.screecher_nofx ) && level.screecher_nofx )
  443.     {
  444.         return;
  445. #/
  446.     }
  447.     playfx( level._effect[ "screecher_spawn_a" ], self.origin, ( 0, 0, 1 ) );
  448.     playfx( level._effect[ "screecher_spawn_b" ], self.origin, ( 0, 0, 1 ) );
  449.     self waittill( "risen" );
  450.     playfx( level._effect[ "screecher_spawn_c" ], self.origin, ( 0, 0, 1 ) );
  451. }
  452.  
  453. play_screecher_damaged_yelps()
  454. {
  455.     self endon( "death" );
  456.     while ( 1 )
  457.     {
  458.         self waittill( "damage", damage, attacker, dir, point, mod );
  459.         if ( isDefined( attacker ) && isplayer( attacker ) )
  460.         {
  461.             self playsound( "zmb_vocals_screecher_pain" );
  462.         }
  463.     }
  464. }
  465.  
  466. play_screecher_breathing_audio()
  467. {
  468.     wait 0,5;
  469.     if ( !isDefined( self ) )
  470.     {
  471.         return;
  472.     }
  473.     if ( !isDefined( self.loopsoundent ) )
  474.     {
  475.         self.loopsoundent = spawn( "script_origin", self.origin );
  476.         self.loopsoundent linkto( self, "tag_origin" );
  477.     }
  478.     self.loopsoundent playloopsound( "zmb_vocals_screecher_breath" );
  479. }
  480.  
  481. screecher_rise()
  482. {
  483.     self endon( "death" );
  484.     self animscripted( self.origin, self.angles, "zm_rise" );
  485.     maps/mp/animscripts/zm_shared::donotetracks( "rise_anim" );
  486.     self notify( "risen" );
  487.     self setfreecameralockonallowed( 1 );
  488.     self.startinglocation = self.origin;
  489.     self thread screecher_zombie_think();
  490.     self thread play_screecher_breathing_audio();
  491. /#
  492. #/
  493. }
  494.  
  495. screecher_zombie_think()
  496. {
  497.     self endon( "death" );
  498.     min_dist = 96;
  499.     max_dist = 144;
  500.     height_tolerance = 32;
  501.     self.state = "chase_init";
  502.     self.isattacking = 0;
  503.     self.nextspecial = getTime();
  504.     for ( ;; )
  505.     {
  506.         switch( self.state )
  507.         {
  508.             case "chase_init":
  509.                 self screecher_chase();
  510.                 break;
  511.             case "chase_update":
  512.                 self screecher_chase_update();
  513.                 break;
  514.             case "attacking":
  515.                 self screecher_attacking();
  516.                 break;
  517.         }
  518.         wait 0,1;
  519.     }
  520. }
  521.  
  522. screecher_chase()
  523. {
  524.     self thread screecher_find_flesh();
  525.     self.state = "chase_update";
  526. }
  527.  
  528. screecher_chase_update()
  529. {
  530.     player = self.favoriteenemy;
  531.     if ( isDefined( player ) )
  532.     {
  533.         dist = distance2dsquared( self.origin, player.origin );
  534.         if ( dist < 57600 )
  535.         {
  536.             self screecher_attack();
  537.             return;
  538.         }
  539.         if ( self screecher_should_runaway( player ) )
  540.         {
  541.             self thread screecher_runaway();
  542.             return;
  543.         }
  544.     }
  545. }
  546.  
  547. screecher_attack()
  548. {
  549.     self endon( "death" );
  550.     player = self.favoriteenemy;
  551.     if ( isDefined( player.screecher ) )
  552.     {
  553.         return;
  554.     }
  555.     else
  556.     {
  557.         player.screecher = self;
  558.     }
  559.     self notify( "stop_find_flesh" );
  560.     self notify( "zombie_acquire_enemy" );
  561.     self animmode( "nogravity" );
  562.     self playsound( "zmb_vocals_screecher_jump" );
  563.     if ( isDefined( self.loopsoundent ) )
  564.     {
  565.         self.loopsoundent delete();
  566.         self.loopsoundent = undefined;
  567.     }
  568.     self setanimstatefromasd( "zm_jump_up" );
  569.     maps/mp/animscripts/zm_shared::donotetracks( "jump_up_anim" );
  570.     asd_state = self screecher_fly_to_player( player );
  571.     self setplayercollision( 0 );
  572.     self setclientfield( "render_third_person", 1 );
  573.     self linkto( self.favoriteenemy, "tag_origin" );
  574.     self animscripted( self.favoriteenemy.origin, self.favoriteenemy.angles, asd_state );
  575.     maps/mp/animscripts/zm_shared::donotetracks( "jump_land_success_anim" );
  576.     org = self.favoriteenemy gettagorigin( "j_head" );
  577.     angles = self.favoriteenemy gettagangles( "j_head" );
  578.     self forceteleport( org, angles );
  579.     self linkto( self.favoriteenemy, "j_head" );
  580.     self animscripted( self.origin, self.angles, "zm_headpull" );
  581.     self.linked_ent = self.favoriteenemy;
  582.     self.linked_ent setmovespeedscale( 0,5 );
  583.     self thread screecher_melee_button_watcher();
  584.     self screecher_start_attack();
  585. }
  586.  
  587. screecher_fly_to_player( player )
  588. {
  589.     self endon( "death" );
  590.     self setanimstatefromasd( "zm_jump_loop" );
  591.     self.anchor.origin = self.origin;
  592.     self.anchor.angles = self.angles;
  593.     self linkto( self.anchor );
  594.     anim_id_back = self getanimfromasd( "zm_jump_land_success_fromback", 0 );
  595.     anim_id_front = self getanimfromasd( "zm_jump_land_success_fromfront", 0 );
  596.     end_time = getTime() + 2500;
  597.     dist = undefined;
  598.     dist_update = undefined;
  599.     while ( end_time > getTime() )
  600.     {
  601.         goal_pos_back = getstartorigin( player.origin, player.angles, anim_id_back );
  602.         goal_pos_front = getstartorigin( player.origin, player.angles, anim_id_front );
  603.         dist_back = distancesquared( self.anchor.origin, goal_pos_back );
  604.         dist_front = distancesquared( self.anchor.origin, goal_pos_front );
  605.         goal_pos = goal_pos_back;
  606.         goal_ang = getstartangles( player.origin, player.angles, anim_id_back );
  607.         asd_state = "zm_jump_land_success_fromback";
  608.         if ( dist_front < dist_back )
  609.         {
  610.             goal_pos = goal_pos_front;
  611.             goal_ang = getstartangles( player.origin, player.angles, anim_id_front );
  612.             asd_state = "zm_jump_land_success_fromfront";
  613.         }
  614.         facing_vec = goal_pos - self.anchor.origin;
  615.         facing_angles = vectorToAngle( facing_vec );
  616.         dist = length( facing_vec );
  617.         if ( !isDefined( dist_update ) )
  618.         {
  619.             time = 0,5;
  620.             vel = dist / time;
  621.             dist_update = vel * 0,1;
  622.         }
  623.         if ( dist < dist_update )
  624.         {
  625.             self.anchor.origin = goal_pos;
  626.             self.anchor.angles = goal_ang;
  627.             break;
  628.         }
  629.         else
  630.         {
  631.             self.anchor.angles = facing_angles;
  632.             unit_facing_vec = vectornormalize( facing_vec );
  633.             new_pos = self.anchor.origin + vectorScale( unit_facing_vec, dist_update );
  634.             self.anchor moveto( new_pos, 0,1 );
  635.             wait 0,1;
  636.         }
  637.     }
  638.     return asd_state;
  639. }
  640.  
  641. finish_planting_equipment()
  642. {
  643.     while ( self isthrowinggrenade() && is_equipment( self getcurrentweapon() ) )
  644.     {
  645.         wait 0,05;
  646.     }
  647. }
  648.  
  649. screecher_start_attack()
  650. {
  651.     player = self.favoriteenemy;
  652.     if ( is_player_valid( player ) )
  653.     {
  654.         player playsoundtoplayer( "zmb_screecher_impact", player );
  655.         player finish_planting_equipment();
  656.         player allowprone( 0 );
  657.         player.screecher_weapon = player getcurrentweapon();
  658.         player giveweapon( "screecher_arms_zm" );
  659.         throwing_grenade = 0;
  660.         if ( player isthrowinggrenade() )
  661.         {
  662.             throwing_grenade = 1;
  663.             primaryweapons = player getweaponslistprimaries();
  664.             if ( isDefined( primaryweapons ) && primaryweapons.size > 0 )
  665.             {
  666.                 player.screecher_weapon = primaryweapons[ 0 ];
  667.                 player forcegrenadethrow();
  668.                 player switchtoweaponimmediate( "screecher_arms_zm" );
  669.             }
  670.         }
  671.         else if ( player.screecher_weapon == "riotshield_zm" )
  672.         {
  673.             player switchtoweaponimmediate( "screecher_arms_zm" );
  674.         }
  675.         else
  676.         {
  677.             player switchtoweapon( "screecher_arms_zm" );
  678.         }
  679.         player increment_is_drinking();
  680.         wait 0,5;
  681.         player clientnotify( "scrStrt" );
  682.         if ( player isthrowinggrenade() && !throwing_grenade )
  683.         {
  684.             primaryweapons = player getweaponslistprimaries();
  685.             if ( isDefined( primaryweapons ) && primaryweapons.size > 0 )
  686.             {
  687.                 player.screecher_weapon = primaryweapons[ 0 ];
  688.                 player forcegrenadethrow();
  689.                 player switchtoweaponimmediate( "screecher_arms_zm" );
  690.             }
  691.         }
  692.         self.state = "attacking";
  693.         self.attack_time = getTime();
  694.         if ( !getDvarInt( #"E7EF8EB7" ) )
  695.         {
  696.             player startpoisoning();
  697.         }
  698.         self thread screecher_player_down();
  699.     }
  700.     else
  701.     {
  702.         self screecher_detach( player );
  703.     }
  704. }
  705.  
  706. screecher_player_down()
  707. {
  708.     self endon( "death" );
  709.     self endon( "runaway" );
  710.     player = self.linked_ent;
  711.     player endon( "death" );
  712.     player endon( "disconnect" );
  713.     player waittill( "player_downed" );
  714.     self thread screecher_detach( player );
  715. }
  716.  
  717. screecher_first_seen_hint_think()
  718. {
  719.     if ( !flag( "solo_game" ) )
  720.     {
  721.         return;
  722.     }
  723.     fade_time = 3;
  724.     hudelem = self maps/mp/gametypes_zm/_hud_util::createfontstring( "objective", 2 );
  725.     hudelem maps/mp/gametypes_zm/_hud_util::setpoint( "TOP", undefined, 0, 200 );
  726.     hudelem.label = &"ZOMBIE_SCREECHER_ATTACH_FIRST";
  727.     hudelem.sort = 0,5;
  728.     hudelem.alpha = 1;
  729.     hudelem fadeovertime( fade_time );
  730.     hudelem.alpha = 0;
  731.     wait fade_time;
  732.     hudelem destroy();
  733. }
  734.  
  735. screecher_attacking()
  736. {
  737.     player = self.favoriteenemy;
  738.     if ( !isDefined( player ) )
  739.     {
  740.         self thread screecher_detach( player );
  741.         return;
  742.     }
  743.     if ( isDefined( player.screecher_seen_hint ) && !player.screecher_seen_hint )
  744.     {
  745.         player thread screecher_first_seen_hint_think();
  746.         player.screecher_seen_hint = 1;
  747.     }
  748.     if ( screecher_should_runaway( player ) )
  749.     {
  750.         self thread screecher_detach( player );
  751.         player thread do_player_general_vox( "general", "screecher_jumpoff" );
  752.         return;
  753.     }
  754.     if ( self.attack_time < getTime() )
  755.     {
  756.         scratch_score = 5;
  757.         players = get_players();
  758.         self.screecher_score += scratch_score;
  759.         killed_player = self screecher_check_score();
  760.         if ( player.health > 0 && isDefined( killed_player ) && !killed_player )
  761.         {
  762.             self.attack_delay = self.attack_delay_base + randomint( self.attack_delay_offset );
  763.             self.attack_time = getTime() + self.attack_delay;
  764.             self thread claw_fx( player, self.attack_delay * 0,001 );
  765.             self playsound( "zmb_vocals_screecher_attack" );
  766.             player playsoundtoplayer( "zmb_screecher_scratch", player );
  767.             player thread do_player_general_vox( "general", "screecher_attack" );
  768.             players = get_players();
  769.             if ( players.size == 1 )
  770.             {
  771.                 if ( level.near_miss == 0 )
  772.                 {
  773.                     level.near_miss = 1;
  774. /#
  775.                     screecher_print( "first attack near_miss " + level.near_miss );
  776. #/
  777.                 }
  778.             }
  779.         }
  780.     }
  781. }
  782.  
  783. screecher_runaway()
  784. {
  785.     self endon( "death" );
  786. /#
  787.     screecher_print( "runaway" );
  788. #/
  789.     self notify( "stop_find_flesh" );
  790.     self notify( "zombie_acquire_enemy" );
  791.     self notify( "runaway" );
  792.     self.state = "runaway";
  793.     self.ignoreall = 1;
  794.     self setgoalpos( self.startinglocation );
  795.     self waittill( "goal" );
  796.     playfx( level._effect[ "screecher_spawn_b" ], self.origin, ( 0, 0, 1 ) );
  797.     self.no_powerups = 1;
  798.     self setfreecameralockonallowed( 0 );
  799.     self animscripted( self.origin, self.angles, "zm_burrow" );
  800.     self playsound( "zmb_screecher_dig" );
  801.     maps/mp/animscripts/zm_shared::donotetracks( "burrow_anim" );
  802.     self delete();
  803. }
  804.  
  805. screecher_detach( player )
  806. {
  807.     self endon( "death" );
  808.     self.state = "detached";
  809.     if ( !isDefined( self.linked_ent ) )
  810.     {
  811.         return;
  812.     }
  813. /#
  814.     screecher_print( "detach" );
  815. #/
  816.     if ( isDefined( player ) )
  817.     {
  818.         player clientnotify( "scrEnd" );
  819.         if ( isDefined( player.isonbus ) && !player.isonbus )
  820.         {
  821.             player allowprone( 1 );
  822.         }
  823.         player takeweapon( "screecher_arms_zm" );
  824.         if ( !getDvarInt( #"E7EF8EB7" ) )
  825.         {
  826.             player stoppoisoning();
  827.         }
  828.         if ( !player maps/mp/zombies/_zm_laststand::player_is_in_laststand() && isDefined( player.intermission ) && !player.intermission )
  829.         {
  830.             player decrement_is_drinking();
  831.         }
  832.         if ( isDefined( player.screecher_weapon ) && player.screecher_weapon != "none" && is_player_valid( player ) && !is_equipment_that_blocks_purchase( player.screecher_weapon ) )
  833.         {
  834.             player switchtoweapon( player.screecher_weapon );
  835.         }
  836.         else
  837.         {
  838.             if ( flag( "solo_game" ) && player hasperk( "specialty_quickrevive" ) )
  839.             {
  840.             }
  841.             else
  842.             {
  843.                 if ( !player maps/mp/zombies/_zm_laststand::player_is_in_laststand() )
  844.                 {
  845.                     primaryweapons = player getweaponslistprimaries();
  846.                     if ( isDefined( primaryweapons ) && primaryweapons.size > 0 )
  847.                     {
  848.                         player switchtoweapon( primaryweapons[ 0 ] );
  849.                     }
  850.                 }
  851.             }
  852.         }
  853.         player.screecher_weapon = undefined;
  854.     }
  855.     self unlink();
  856.     self setclientfield( "render_third_person", 0 );
  857.     if ( isDefined( self.linked_ent ) )
  858.     {
  859.         self.linked_ent.screecher = undefined;
  860.         self.linked_ent setmovespeedscale( 1 );
  861.         self.linked_ent = undefined;
  862.     }
  863.     self.green_light = player.green_light;
  864.     self animcustom( ::screecher_jump_down );
  865.     self waittill( "jump_down_done" );
  866.     maps/mp/_visionset_mgr::vsmgr_deactivate( "overlay", "zm_ai_screecher_blur", player );
  867.     self animmode( "normal" );
  868.     self.ignoreall = 1;
  869.     self setplayercollision( 1 );
  870.     if ( isDefined( level.screecher_should_burrow ) )
  871.     {
  872.         if ( self [[ level.screecher_should_burrow ]]() )
  873.         {
  874. /#
  875.             screecher_print( "should burrow" );
  876. #/
  877.             return;
  878.         }
  879.     }
  880.     self thread screecher_runaway();
  881. }
  882.  
  883. screecher_jump_down()
  884. {
  885.     self endon( "death" );
  886.     self setanimstatefromasd( "zm_headpull_success" );
  887.     wait 0,6;
  888.     self notify( "jump_down_done" );
  889. }
  890.  
  891. create_claw_fx_hud( player )
  892. {
  893.     self.claw_fx = newclienthudelem( player );
  894.     self.claw_fx.horzalign = "fullscreen";
  895.     self.claw_fx.vertalign = "fullscreen";
  896. }
  897.  
  898. choose_claw_fx()
  899. {
  900.     direction = [];
  901.     direction[ direction.size ] = "fullscreen_claw_left";
  902.     direction[ direction.size ] = "fullscreen_claw_right";
  903.     direction[ direction.size ] = "fullscreen_claw_bottom";
  904.     direction = array_randomize( direction );
  905.     self.claw_fx setshader( direction[ 0 ], 640, 480 );
  906.     self.claw_fx.alpha = 1;
  907. }
  908.  
  909. claw_fx( player, timeout )
  910. {
  911.     self endon( "death" );
  912.     claw_timeout = 0,25;
  913.     if ( !isDefined( self.claw_fx ) )
  914.     {
  915.         self create_claw_fx_hud( player );
  916.     }
  917.     self choose_claw_fx();
  918.     self.claw_fx fadeovertime( claw_timeout );
  919.     self.claw_fx.alpha = 0;
  920.     earthquake( randomfloatrange( 0,4, 0,5 ), claw_timeout, player.origin, 250 );
  921.     maps/mp/_visionset_mgr::vsmgr_activate( "overlay", "zm_ai_screecher_blur", player, 0,25 );
  922. }
  923.  
  924. screecher_cleanup()
  925. {
  926.     self waittill( "death", attacker );
  927.     if ( isDefined( attacker ) && isplayer( attacker ) )
  928.     {
  929.         if ( isDefined( self.damagelocation ) && isDefined( self.damagemod ) )
  930.         {
  931.             level thread maps/mp/zombies/_zm_audio::player_zombie_kill_vox( self.damagelocation, attacker, self.damagemod, self );
  932.         }
  933.     }
  934.     if ( isDefined( self.loopsoundent ) )
  935.     {
  936.         self.loopsoundent delete();
  937.         self.loopsoundent = undefined;
  938.     }
  939.     player = self.linked_ent;
  940.     if ( isDefined( player ) )
  941.     {
  942.         player playsound( "zmb_vocals_screecher_death" );
  943.         player setmovespeedscale( 1 );
  944.         maps/mp/_visionset_mgr::vsmgr_deactivate( "overlay", "zm_ai_screecher_blur", player );
  945.         if ( isDefined( player.screecher_weapon ) )
  946.         {
  947.             player clientnotify( "scrEnd" );
  948.             if ( isDefined( player.isonbus ) && !player.isonbus )
  949.             {
  950.                 player allowprone( 1 );
  951.             }
  952.             player takeweapon( "screecher_arms_zm" );
  953.             if ( !getDvarInt( #"E7EF8EB7" ) )
  954.             {
  955.                 player stoppoisoning();
  956.             }
  957.             if ( !player maps/mp/zombies/_zm_laststand::player_is_in_laststand() && isDefined( player.intermission ) && !player.intermission )
  958.             {
  959.                 player decrement_is_drinking();
  960.             }
  961.             if ( player.screecher_weapon != "none" && is_player_valid( player ) )
  962.             {
  963.                 player switchtoweapon( player.screecher_weapon );
  964.             }
  965.             else
  966.             {
  967.                 primaryweapons = player getweaponslistprimaries();
  968.                 if ( isDefined( primaryweapons ) && primaryweapons.size > 0 )
  969.                 {
  970.                     player switchtoweapon( primaryweapons[ 0 ] );
  971.                 }
  972.             }
  973.             player.screecher_weapon = undefined;
  974.         }
  975.     }
  976.     if ( isDefined( self.claw_fx ) )
  977.     {
  978.         self.claw_fx destroy();
  979.     }
  980.     if ( isDefined( self.anchor ) )
  981.     {
  982.         self.anchor delete();
  983.     }
  984.     if ( isDefined( level.screecher_cleanup ) )
  985.     {
  986.         self [[ level.screecher_cleanup ]]();
  987.     }
  988.     if ( level.zombie_screecher_count > 0 )
  989.     {
  990.         level.zombie_screecher_count--;
  991.  
  992. /#
  993.         screecher_print( "screecher total " + level.zombie_screecher_count );
  994. #/
  995.     }
  996. }
  997.  
  998. screecher_distance_tracking()
  999. {
  1000.     self endon( "death" );
  1001.     while ( 1 )
  1002.     {
  1003.         can_delete = 1;
  1004.         players = get_players();
  1005.         _a1304 = players;
  1006.         _k1304 = getFirstArrayKey( _a1304 );
  1007.         while ( isDefined( _k1304 ) )
  1008.         {
  1009.             player = _a1304[ _k1304 ];
  1010.             if ( player.sessionstate == "spectator" )
  1011.             {
  1012.             }
  1013.             else dist_sq = distancesquared( self.origin, player.origin );
  1014.             if ( dist_sq >= 4000000 )
  1015.             {
  1016.             }
  1017.             else
  1018.             {
  1019.                 can_see = player maps/mp/zombies/_zm_utility::is_player_looking_at( self.origin, 0,9, 0 );
  1020.                 if ( can_see || dist_sq < 1000000 )
  1021.                 {
  1022.                     can_delete = 0;
  1023.                     break;
  1024.                 }
  1025.             }
  1026.             else
  1027.             {
  1028.                 _k1304 = getNextArrayKey( _a1304, _k1304 );
  1029.             }
  1030.         }
  1031.         if ( can_delete )
  1032.         {
  1033.             self notify( "zombie_delete" );
  1034.             if ( isDefined( self.anchor ) )
  1035.             {
  1036.                 self.anchor delete();
  1037.             }
  1038.             self delete();
  1039.             recalc_zombie_array();
  1040.         }
  1041.         wait 0,1;
  1042.     }
  1043. }
  1044.  
  1045. screecher_melee_button_watcher()
  1046. {
  1047.     self endon( "death" );
  1048.     while ( isDefined( self.linked_ent ) )
  1049.     {
  1050.         player = self.linked_ent;
  1051.         while ( player meleebuttonpressed() && player ismeleeing() )
  1052.         {
  1053.             self screecher_melee_damage( player );
  1054.             while ( player meleebuttonpressed() || player ismeleeing() )
  1055.             {
  1056.                 wait 0,05;
  1057.             }
  1058.         }
  1059.         wait 0,05;
  1060.     }
  1061. }
  1062.  
  1063. screecher_melee_damage( player )
  1064. {
  1065.     one_player = 0;
  1066.     melee_score = 0;
  1067.     if ( player hasweapon( "bowie_knife_zm" ) )
  1068.     {
  1069.         if ( one_player )
  1070.         {
  1071.             melee_score = 30;
  1072.         }
  1073.         else
  1074.         {
  1075.             melee_score = 10;
  1076.         }
  1077.     }
  1078.     else if ( player hasweapon( "tazer_knuckles_zm" ) )
  1079.     {
  1080.         if ( one_player )
  1081.         {
  1082.             melee_score = 30;
  1083.         }
  1084.         else
  1085.         {
  1086.             melee_score = 15;
  1087.         }
  1088.     }
  1089.     else if ( one_player )
  1090.     {
  1091.         melee_score = 15;
  1092.     }
  1093.     else
  1094.     {
  1095.         melee_score = 6;
  1096.     }
  1097.     extra_score = 0;
  1098.     if ( self.screecher_score > 0 && !one_player )
  1099.     {
  1100.         if ( melee_score > self.screecher_score )
  1101.         {
  1102.             extra_score = melee_score - self.screecher_score;
  1103.             self.screecher_score = 0;
  1104.         }
  1105.         else
  1106.         {
  1107.             self.screecher_score -= melee_score;
  1108.         }
  1109.     }
  1110.     if ( self.screecher_score <= 0 || one_player )
  1111.     {
  1112.         self.player_score += melee_score;
  1113.         if ( extra_score > 0 )
  1114.         {
  1115.             self.player_score += extra_score;
  1116.         }
  1117.     }
  1118.     self playsound( "zmb_vocals_screecher_pain" );
  1119.     if ( level.zombie_vars[ player.team ][ "zombie_insta_kill" ] )
  1120.     {
  1121.         self.player_score = 30;
  1122.     }
  1123.     else
  1124.     {
  1125.         player thread do_player_general_vox( "general", "screecher_cut" );
  1126.     }
  1127. /#
  1128.     if ( getDvarInt( #"6A65F83E" ) )
  1129.     {
  1130.         self.player_score = 30;
  1131. #/
  1132.     }
  1133.     self screecher_check_score();
  1134. }
  1135.  
  1136. screecher_damage_func( einflictor, eattacker, idamage, idflags, smeansofdeath, sweapon, vpoint, vdir, shitloc, psoffsettime, boneindex )
  1137. {
  1138.     if ( isDefined( self.linked_ent ) )
  1139.     {
  1140.         if ( isplayer( einflictor ) && smeansofdeath == "MOD_MELEE" )
  1141.         {
  1142.             return 0;
  1143.         }
  1144.     }
  1145.     return idamage;
  1146. }
  1147.  
  1148. screecher_death_func()
  1149. {
  1150.     self unlink();
  1151.     self.noragdoll = 1;
  1152.     self setanimstatefromasd( "zm_death" );
  1153.     maps/mp/animscripts/zm_shared::donotetracks( "death_anim" );
  1154.     playfx( level._effect[ "screecher_death" ], self.origin );
  1155.     if ( isDefined( self.attacker ) && isplayer( self.attacker ) )
  1156.     {
  1157.         self.attacker maps/mp/zombies/_zm_stats::increment_client_stat( "screechers_killed", 0 );
  1158.         self.attacker maps/mp/zombies/_zm_stats::increment_player_stat( "screechers_killed" );
  1159.     }
  1160.     self delete();
  1161.     return 1;
  1162. }
  1163.  
  1164. screecher_check_score()
  1165. {
  1166.     if ( self.player_score >= 30 )
  1167.     {
  1168.         player = self.linked_ent;
  1169.         if ( isDefined( player ) )
  1170.         {
  1171.             player notify( "i_dont_think_they_exist" );
  1172.             player maps/mp/zombies/_zm_stats::increment_client_stat( "screecher_minigames_won", 0 );
  1173.             player maps/mp/zombies/_zm_stats::increment_player_stat( "screecher_minigames_won" );
  1174.         }
  1175.         self dodamage( self.health + 666, self.origin );
  1176.     }
  1177.     else
  1178.     {
  1179.         if ( self.screecher_score >= 15 )
  1180.         {
  1181. /#
  1182.             if ( getDvarInt( #"6A65F83E" ) )
  1183.             {
  1184.                 return 0;
  1185. #/
  1186.             }
  1187.             player = self.linked_ent;
  1188.             if ( isDefined( player ) )
  1189.             {
  1190.                 self.meleedamage = player.health;
  1191.                 player dodamage( player.health, self.origin, self );
  1192.                 self screecher_detach( player );
  1193.                 player maps/mp/zombies/_zm_stats::increment_client_stat( "screecher_minigames_lost", 0 );
  1194.                 player maps/mp/zombies/_zm_stats::increment_player_stat( "screecher_minigames_lost" );
  1195.                 return 1;
  1196.             }
  1197.         }
  1198.     }
  1199. /#
  1200.     screecher_print( "score: player " + self.player_score + " screecher " + self.screecher_score );
  1201. #/
  1202.     return 0;
  1203. }
  1204.  
  1205. screecher_debug_axis()
  1206. {
  1207. /#
  1208.     self endon( "death" );
  1209.     while ( 1 )
  1210.     {
  1211.         if ( isDefined( self.favoriteenemy ) )
  1212.         {
  1213.             player = self.favoriteenemy;
  1214.             anim_id = self getanimfromasd( "zm_jump_land_success", 0 );
  1215.             org = getstartorigin( player.origin, player.angles, anim_id );
  1216.             angles = getstartangles( player.origin, player.angles, anim_id );
  1217.             if ( !isDefined( player.bone_fxaxis ) )
  1218.             {
  1219.                 player.bone_fxaxis = spawn( "script_model", org );
  1220.                 player.bone_fxaxis setmodel( "fx_axis_createfx" );
  1221.             }
  1222.             if ( isDefined( player.bone_fxaxis ) )
  1223.             {
  1224.                 player.bone_fxaxis.origin = org;
  1225.                 player.bone_fxaxis.angles = angles;
  1226.             }
  1227.         }
  1228.         wait 0,1;
  1229. #/
  1230.     }
  1231. }
  1232.  
  1233. screecher_print( str )
  1234. {
  1235. /#
  1236.     if ( getDvarInt( #"72C3A9C6" ) )
  1237.     {
  1238.         iprintln( "screecher: " + str + "\n" );
  1239.         if ( isDefined( self ) )
  1240.         {
  1241.             if ( isDefined( self.debug_msg ) )
  1242.             {
  1243.                 self.debug_msg[ self.debug_msg.size ] = str;
  1244.                 return;
  1245.             }
  1246.             else
  1247.             {
  1248.                 self.debug_msg = [];
  1249.                 self.debug_msg[ self.debug_msg.size ] = str;
  1250. #/
  1251.             }
  1252.         }
  1253.     }
  1254. }
Advertisement
Add Comment
Please, Sign In to add comment