Advertisement
Guest User

Untitled

a guest
Feb 5th, 2016
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 39.96 KB | None | 0 0
  1. #include maps\_utility;
  2. #include common_scripts\utility;
  3.  
  4. init_utility()
  5. {
  6. //  level thread edge_fog_start();
  7.  
  8. //  level thread hudelem_count();
  9. }
  10.  
  11. get_enemy_count()
  12. {
  13.     enemies = [];
  14.     valid_enemies = [];
  15.     enemies = GetAiSpeciesArray( "axis", "all" );
  16.     for( i = 0; i < enemies.size; i++ )
  17.     {
  18.         if( enemies[i].animname != "boss_zombie" )
  19.         {
  20.             valid_enemies = array_add( valid_enemies, enemies[i] );
  21.         }
  22.     }
  23.     return valid_enemies.size;
  24. }
  25.  
  26. spawn_zombie( spawner, target_name )
  27. {
  28.     spawner.script_moveoverride = true;
  29.  
  30.     if( IsDefined( spawner.script_forcespawn ) && spawner.script_forcespawn )
  31.     {
  32.         guy = spawner StalingradSpawn();  
  33.     }
  34.     else
  35.     {
  36.         guy = spawner DoSpawn();  
  37.     }
  38.  
  39.     spawner.count = 666;
  40.  
  41. //  // sometimes we want to ensure a zombie will go to a particular door node
  42. //  // so we target the spawner at a struct and put the struct near the entry point
  43. //  if( isdefined( spawner.target ) )
  44. //  {
  45. //      guy.forced_entry = getstruct( spawner.target, "targetname" );
  46. //  }
  47.  
  48.     if( !spawn_failed( guy ) )
  49.     {
  50.         if( IsDefined( target_name ) )
  51.         {
  52.             guy.targetname = target_name;
  53.         }
  54.  
  55.         return guy;  
  56.     }
  57.  
  58.     return undefined;  
  59. }
  60.  
  61. create_simple_hud( client )
  62. {
  63.     if( IsDefined( client ) )
  64.     {
  65.         hud = NewClientHudElem( client );
  66.     }
  67.     else
  68.     {
  69.         hud = NewHudElem();
  70.     }
  71.  
  72.     level.hudelem_count++;
  73.  
  74.     hud.foreground = true;
  75.     hud.sort = 1;
  76.     hud.hidewheninmenu = false;
  77.  
  78.     return hud;
  79. }
  80.  
  81. destroy_hud()
  82. {
  83.     level.hudelem_count--;
  84.     self Destroy();
  85. }
  86.  
  87. all_chunks_intact( barrier_chunks )
  88. {
  89.     for( i = 0; i < barrier_chunks.size; i++ )
  90.     {
  91.         if( barrier_chunks[i].destroyed && !IsDefined( barrier_chunks[i].mid_repair ))
  92.         {
  93.             return false;
  94.         }
  95.     }
  96.  
  97.     return true;
  98. }
  99.  
  100. all_chunks_destroyed( barrier_chunks )
  101. {
  102.     for( i = 0; i < barrier_chunks.size; i++ )
  103.     {
  104.         if( !barrier_chunks[i].destroyed )
  105.         {
  106.             return false;
  107.         }
  108.         if ( IsDefined( barrier_chunks[i].target_by_zombie ) )
  109.         {
  110.             return false;
  111.         }
  112.     }
  113.  
  114.     return true;
  115. }
  116.  
  117. check_point_in_playable_area( origin )
  118. {
  119.     playable_area = getentarray("playable_area","targetname");
  120.  
  121.     check_model = spawn ("script_model", origin + (0,0,40));
  122.    
  123.     valid_point = false;
  124.     for (i = 0; i < playable_area.size; i++)
  125.     {
  126.         if (check_model istouching(playable_area[i]))
  127.         {
  128.             valid_point = true;
  129.         }
  130.     }
  131.    
  132.     check_model delete();
  133.     return valid_point;
  134. }
  135.  
  136. check_point_in_active_zone( origin )
  137. {
  138.     player_zones = GetEntArray( "player_zone", "script_noteworthy" );
  139.     if( !isDefined( level.zones ) || !isDefined( player_zones ) )
  140.     {
  141.         return true;
  142.     }
  143.    
  144.     scr_org = spawn( "script_origin", origin+(0, 0, 40) );
  145.    
  146.     one_valid_zone = false;
  147.     for( i = 0; i < player_zones.size; i++ )
  148.     {
  149.         if( scr_org isTouching( player_zones[i] ) )
  150.         {
  151.             if( isDefined( level.zones[player_zones[i].targetname] ) &&
  152.                 isDefined( level.zones[player_zones[i].targetname].is_enabled ) )
  153.             {
  154.                 one_valid_zone = true;
  155.             }
  156.         }
  157.     }
  158.    
  159.     return one_valid_zone;
  160. }
  161.  
  162. round_up_to_ten( score )
  163. {
  164.     new_score = score - score % 10;
  165.     if( new_score < score )
  166.     {
  167.         new_score += 10;
  168.     }
  169.     return new_score;
  170. }
  171.  
  172. random_tan()
  173. {
  174.     rand = randomint( 100 );
  175.    
  176.     // PI_CHANGE_BEGIN - JMA - only 15% chance that we are going to spawn charred zombies in sumpf
  177.     if(isDefined(level.script) && level.script == "nazi_zombie_sumpf")
  178.     {
  179.         percentNotCharred = 85;
  180.     }
  181.     else
  182.     {
  183.         percentNotCharred = 65;
  184.     }
  185.    
  186.     if( rand > percentNotCharred )
  187.     {
  188.         self StartTanning();
  189.     }
  190.     // PI_CHANGE_END
  191. }
  192.  
  193. // Returns the amount of places before the decimal, ie 1000 = 4, 100 = 3...
  194. places_before_decimal( num )
  195. {
  196.     abs_num = abs( num );
  197.     count = 0;
  198.     while( 1 )
  199.     {
  200.         abs_num *= 0.1; // Really doing num / 10
  201.         count += 1;
  202.  
  203.         if( abs_num < 1 )
  204.         {
  205.             return count;
  206.         }
  207.     }
  208. }
  209.  
  210. create_zombie_point_of_interest( attract_dist, num_attractors, added_poi_value, start_turned_on )
  211. {
  212.     if( !isDefined( added_poi_value ) )
  213.     {
  214.         self.added_poi_value = 0;
  215.     }
  216.     else
  217.     {
  218.         self.added_poi_value = added_poi_value;
  219.     }
  220.    
  221.     if( !isDefined( start_turned_on ) )
  222.     {
  223.         start_turned_on = true;
  224.     }
  225.    
  226.     self.script_noteworthy = "zombie_poi";
  227.     self.poi_active = start_turned_on;
  228.  
  229.     if( isDefined( attract_dist ) )
  230.     {
  231.         self.poi_radius = attract_dist * attract_dist;
  232.     }
  233.     else // This poi has no maximum attract distance, it will attract all zombies
  234.     {
  235.         self.poi_radius = undefined;
  236.     }
  237.     self.num_poi_attracts = num_attractors;
  238.     self.attract_to_origin = true;
  239. }
  240.  
  241. create_zombie_point_of_interest_attractor_positions( num_attract_dists, diff_per_dist, attractor_width )
  242. {
  243.     forward = ( 0, 1, 0 );
  244.    
  245.     if( !isDefined( self.num_poi_attracts ) || self.script_noteworthy != "zombie_poi" )
  246.     {
  247.         return;
  248.     }
  249.    
  250.     if( !isDefined( num_attract_dists ) )
  251.     {
  252.         num_attract_dists = 4;
  253.     }
  254.    
  255.     if( !isDefined( diff_per_dist ) )
  256.     {
  257.         diff_per_dist = 45;
  258.     }
  259.    
  260.     if( !isDefined( attractor_width ) )
  261.     {
  262.         attractor_width = 45;
  263.     }
  264.    
  265.     self.attract_to_origin = false;
  266.    
  267.     self.num_attract_dists = num_attract_dists;
  268.    
  269.     // The last index in the attractor_position arrays for each of the four distances
  270.     self.last_index = [];
  271.     for( i = 0; i < num_attract_dists; i++ )
  272.     {
  273.         self.last_index[i] = -1;
  274.     }
  275.    
  276.     self.attract_dists = [];
  277.     for( i = 0; i < self.num_attract_dists; i++ )
  278.     {
  279.         self.attract_dists[i] = diff_per_dist * (i+1);
  280.     }
  281.    
  282.     // Array of max positions per distance
  283.     // 0 = close, 1 = med, 2 = far, 3 = very far
  284.     max_positions = [];
  285.     for( i = 0; i < self.num_attract_dists; i++ )
  286.     {
  287.         max_positions[i] = int(3.14*2*self.attract_dists[i]/attractor_width);
  288.     }
  289.    
  290.     num_attracts_per_dist = self.num_poi_attracts/self.num_attract_dists;
  291.    
  292.     self.max_attractor_dist = self.attract_dists[ self.attract_dists.size - 1 ] * 1.1; // Give some wiggle room for assigning nodes
  293.    
  294.     diff = 0;
  295.    
  296.     self thread debug_draw_attractor_positions();
  297.    
  298.     // Determine the ideal number of attracts based on what a distance can actually hold after any bleed from closer
  299.     // distances is added to the calculated
  300.     actual_num_positions = [];
  301.     for( i = 0; i < self.num_attract_dists; i++ )
  302.     {
  303.         if( num_attracts_per_dist > (max_positions[i]+diff) )
  304.         {
  305.             actual_num_positions[i] = max_positions[i];
  306.             diff += num_attracts_per_dist - max_positions[i];
  307.         }
  308.         else
  309.         {
  310.             actual_num_positions[i] = num_attracts_per_dist + diff;
  311.             diff = 0;
  312.         }  
  313.     }
  314.    
  315.     // Determine the actual positions that will be used, including failed nodes from closer distances, index zero is always the origin
  316.     self.attractor_positions = [];
  317.     failed = 0;
  318.     angle_offset = 0; // Angle offset, used to make nodes not all perfectly radial
  319.     prev_last_index = -1;
  320.     for( j = 0; j < 4; j++ )
  321.     {
  322.         if( (actual_num_positions[j]+failed) < max_positions[j] )
  323.         {
  324.             actual_num_positions[j] += failed;
  325.             failed = 0;
  326.         }
  327.         else if( actual_num_positions[j] < max_positions[j] )
  328.         {
  329.             actual_num_positions[j] = max_positions[j];
  330.             failed = max_positions[j] - actual_num_positions[j];
  331.         }
  332.         failed += self generated_radius_attract_positions( forward, angle_offset, actual_num_positions[j], self.attract_dists[j] );
  333.         angle_offset += 15;
  334.         self.last_index[j] = int(actual_num_positions[j] - failed + prev_last_index);
  335.         prev_last_index = self.last_index[j];
  336.     }
  337.    
  338.     self notify( "attractor_positions_generated" );
  339. }
  340.  
  341. generated_radius_attract_positions( forward, offset, num_positions, attract_radius )
  342. {
  343.     failed = 0;
  344.     degs_per_pos = 360 / num_positions;
  345.     for( i = offset; i < 360+offset; i += degs_per_pos )
  346.     {
  347.         altforward = forward * attract_radius;
  348.         rotated_forward = ( (cos(i)*altforward[0] - sin(i)*altforward[1]), (sin(i)*altforward[0] + cos(i)*altforward[1]), altforward[2] );
  349.         pos = maps\_zombiemode_server_throttle::server_safe_ground_trace( "poi_trace", 10, self.origin + rotated_forward + ( 0, 0, 100 ) );
  350.         if( abs( pos[2] - self.origin[2] ) < 60 )
  351.         {
  352.             pos_array = [];
  353.             pos_array[0] = pos;
  354.             pos_array[1] = self;
  355.             self.attractor_positions = array_add( self.attractor_positions , pos_array );
  356.         }
  357.         else
  358.         {
  359.             failed++;
  360.         }
  361.     }
  362.     return failed;
  363. }
  364.  
  365. debug_draw_attractor_positions()
  366. {
  367.     /#
  368.     while( true )
  369.     {
  370.         while( !isDefined( self.attractor_positions ) )
  371.         {
  372.             wait( 0.05 );
  373.             continue;
  374.         }
  375.         for( i = 0; i < self.attractor_positions.size; i++ )
  376.         {
  377.             Line( self.origin, self.attractor_positions[i][0], (1, 0, 0), true, 1 );
  378.         }
  379.         wait( 0.05 );
  380.         if( !IsDefined( self ) )
  381.         {
  382.             return;
  383.         }
  384.     }
  385.     #/
  386. }
  387.  
  388.  
  389. get_zombie_point_of_interest( origin )
  390. {
  391.     curr_radius = undefined;
  392.    
  393.     ent_array = getEntArray( "zombie_poi", "script_noteworthy" );
  394.    
  395.     best_poi = undefined;
  396.     position = undefined;
  397.     best_dist = 10000 * 10000;
  398.    
  399.     for( i = 0; i < ent_array.size; i++ )
  400.     {
  401.         if( !isDefined( ent_array[i].poi_active ) || !ent_array[i].poi_active  )
  402.         {
  403.             continue;
  404.         }
  405.        
  406.         dist = distanceSquared( origin, ent_array[i].origin );
  407.        
  408.         dist -= ent_array[i].added_poi_value;
  409.        
  410.         if( isDefined( ent_array[i].poi_radius ) )
  411.         {
  412.             curr_radius = ent_array[i].poi_radius;
  413.         }
  414.        
  415.         if( (!isDefined( curr_radius ) || dist < curr_radius) && dist < best_dist && ent_array[i] can_attract(self) )
  416.         {
  417.             best_poi = ent_array[i];
  418.         }
  419.     }
  420.    
  421.     if( isDefined( best_poi ) )
  422.     {
  423.         // Override, currently only used for monkeys in the air.
  424.         if( isDefined( best_poi.attract_to_origin ) && best_poi.attract_to_origin )
  425.         {
  426.             position = [];
  427.             position[0] = groundpos( best_poi.origin + (0, 0, 100) );
  428.             position[1] = self;
  429.         }
  430.         else
  431.         {
  432.             position = self add_poi_attractor( best_poi );
  433.         }
  434.     }
  435.    
  436.     return position;
  437. }
  438.  
  439. activate_zombie_point_of_interest()
  440. {
  441.     if( self.script_noteworthy != "zombie_poi" )
  442.     {
  443.         return;
  444.     }
  445.    
  446.     self.poi_active = true;
  447. }
  448.  
  449. deactivate_zombie_point_of_interest()
  450. {
  451.     if( self.script_noteworthy != "zombie_poi" )
  452.     {
  453.         return;
  454.     }
  455.    
  456.     self.poi_active = false;
  457. }
  458.  
  459. //PI_CHANGE_BEGIN - 6/18/09 JV This works to help set "wait" points near the stage if all players are in the process teleportation.  
  460. //It is unlike the previous function in that you dictate the poi.
  461. assign_zombie_point_of_interest (origin, poi)
  462. {
  463.     position = undefined;
  464.     doremovalthread = false;
  465.  
  466.     if (IsDefined(poi) && poi can_attract(self))
  467.     {
  468.         //don't want to touch add poi attractor, but yeah, this is kind of weird
  469.         if (!IsDefined(poi.attractor_array) || ( IsDefined(poi.attractor_array) && array_check_for_dupes( poi.attractor_array, self ) ))
  470.             doremovalthread = true;
  471.        
  472.         position = self add_poi_attractor( poi );
  473.        
  474.         //now that I know this is the first time they've been added, set up the thread to remove them from the array
  475.         if (IsDefined(position) && doremovalthread && !array_check_for_dupes( poi.attractor_array, self  ))
  476.             self thread update_on_poi_removal( poi );      
  477.     }
  478.    
  479.     return position;
  480. }
  481. //PI_CHANGE_END
  482.  
  483. remove_poi_attractor( zombie_poi )
  484. {
  485.     if( !isDefined( zombie_poi.attractor_array ) )
  486.     {
  487.         return;
  488.     }
  489.    
  490.     for( i = 0; i < zombie_poi.attractor_array.size; i++ )
  491.     {
  492.         if( zombie_poi.attractor_array[i] == self )
  493.         {
  494.             self notify( "kill_poi" );
  495.            
  496.             zombie_poi.attractor_array = array_remove( zombie_poi.attractor_array, zombie_poi.attractor_array[i] );
  497.             zombie_poi.claimed_attractor_positions = array_remove( zombie_poi.claimed_attractor_positions, zombie_poi.claimed_attractor_positions[i] );
  498.         }
  499.     }
  500. }
  501.  
  502. add_poi_attractor( zombie_poi )
  503. {
  504.     if( !isDefined( zombie_poi ) )
  505.     {
  506.         return;
  507.     }
  508.     if( !isDefined( zombie_poi.attractor_array ) )
  509.     {
  510.         zombie_poi.attractor_array = [];
  511.     }
  512.    
  513.     // If we are not yet an attractor to this poi, claim an attractor position and start attracting to it
  514.     if( array_check_for_dupes( zombie_poi.attractor_array, self ) )
  515.     {
  516.         if( !isDefined( zombie_poi.claimed_attractor_positions ) )
  517.         {
  518.             zombie_poi.claimed_attractor_positions = [];
  519.         }
  520.        
  521.         if( !isDefined( zombie_poi.attractor_positions ) || zombie_poi.attractor_positions.size <= 0 )
  522.         {
  523.             return undefined;
  524.         }
  525.        
  526.         start = -1;
  527.         end = -1;
  528.         last_index = -1;
  529.         for( i = 0; i < 4; i++ )
  530.         {
  531.             if( zombie_poi.claimed_attractor_positions.size < zombie_poi.last_index[i] )
  532.             {
  533.                 start = last_index+1;
  534.                 end = zombie_poi.last_index[i];
  535.                 break;
  536.             }
  537.             last_index = zombie_poi.last_index[i];
  538.         }
  539.        
  540.        
  541.         best_dist = 10000*10000;
  542.         best_pos = undefined;
  543.         if( start < 0 )
  544.         {
  545.             start = 0;
  546.         }
  547.         if( end < 0 )
  548.         {
  549.             return undefined;
  550.         }
  551.         for( i = int(start); i <= int(end); i++ )
  552.         {
  553.             if( array_check_for_dupes( zombie_poi.claimed_attractor_positions, zombie_poi.attractor_positions[i] ) )
  554.             {
  555.                 dist = distancesquared( zombie_poi.attractor_positions[i][0], self.origin );
  556.                 if( dist < best_dist || !isDefined( best_pos ) )
  557.                 {
  558.                     best_dist = dist;
  559.                     best_pos = zombie_poi.attractor_positions[i];
  560.                 }
  561.             }
  562.         }
  563.        
  564.         if( !isDefined( best_pos ) )
  565.         {
  566.             return undefined;
  567.         }
  568.        
  569.         zombie_poi.attractor_array = array_add( zombie_poi.attractor_array, self );
  570.         self thread update_poi_on_death( zombie_poi );     
  571.        
  572.         zombie_poi.claimed_attractor_positions = array_add( zombie_poi.claimed_attractor_positions, best_pos );
  573.        
  574.         return best_pos;
  575.     }
  576.     else
  577.     {
  578.         for( i = 0; i < zombie_poi.attractor_array.size; i++ )
  579.         {
  580.             if( zombie_poi.attractor_array[i] == self )
  581.             {
  582.                 if( isDefined( zombie_poi.claimed_attractor_positions ) && isDefined( zombie_poi.claimed_attractor_positions[i] ) )
  583.                 {
  584.                     return zombie_poi.claimed_attractor_positions[i];
  585.                 }
  586.             }
  587.         }
  588.     }
  589.    
  590.     return undefined;
  591. }
  592.  
  593. can_attract( attractor )
  594. {
  595.     if( !isDefined( self.attractor_array ) )
  596.     {
  597.         self.attractor_array = [];
  598.     }
  599.     if( !array_check_for_dupes( self.attractor_array, attractor ) )
  600.     {
  601.         return true;
  602.     }
  603.     if( isDefined(self.num_poi_attracts) && self.attractor_array.size >= self.num_poi_attracts )
  604.     {
  605.         return false;
  606.     }
  607.     return true;
  608. }
  609.  
  610. update_poi_on_death( zombie_poi )
  611. {
  612.     self endon( "kill_poi" );
  613.    
  614.     self waittill( "death" );
  615.     self remove_poi_attractor( zombie_poi );
  616. }
  617.  
  618. //PI_CHANGE_BEGIN - 6/18/09 JV This was set up to work with assign_zombie_point_of_interest (which works with the teleportation in theater).
  619. //The poi attractor array needs to be emptied when a player is teleported out of projection room (if they were all in there).  
  620. //As a result, we wait for the poi's death (I'm sending that notify via the level script)
  621. update_on_poi_removal (zombie_poi )
  622. {  
  623.     zombie_poi waittill( "death" );
  624.    
  625.     if( !isDefined( zombie_poi.attractor_array ) )
  626.         return;
  627.    
  628.     for( i = 0; i < zombie_poi.attractor_array.size; i++ )
  629.     {
  630.         if( zombie_poi.attractor_array[i] == self )
  631.         {  
  632.             zombie_poi.attractor_array = array_remove_index( zombie_poi.attractor_array, i );
  633.             zombie_poi.claimed_attractor_positions = array_remove_index( zombie_poi.claimed_attractor_positions, i );
  634.         }
  635.     }
  636.    
  637. }
  638. //PI_CHANGE_END
  639.  
  640. invalidate_attractor_pos( attractor_pos, zombie )
  641. {
  642.     if( !isDefined( self ) || !isDefined( attractor_pos ) )
  643.     {
  644.         wait( 0.1 );
  645.         return undefined;
  646.     }
  647.    
  648.     if( isDefined( self.attractor_positions) && !array_check_for_dupes( self.attractor_positions, attractor_pos ) )
  649.     {
  650.         index = 0;
  651.         for( i = 0; i < self.attractor_positions.size; i++ )
  652.         {
  653.             if( self.attractor_positions[i] == attractor_pos )
  654.             {
  655.                 index = i;
  656.             }
  657.         }
  658.        
  659.         for( i = 0; i < self.last_index.size; i++ )
  660.         {
  661.             if( index <= self.last_index[i] )
  662.             {
  663.                 self.last_index[i]--;
  664.             }
  665.         }
  666.        
  667.         self.attractor_array = array_remove( self.attractor_array, zombie );
  668.         self.attractor_positions = array_remove( self.attractor_positions, attractor_pos );
  669.         for( i = 0; i < self.claimed_attractor_positions.size; i++ )
  670.         {
  671.             if( self.claimed_attractor_positions[i][0] == attractor_pos[0] )
  672.             {
  673.                 self.claimed_attractor_positions = array_remove( self.claimed_attractor_positions, self.claimed_attractor_positions[i] );
  674.             }
  675.         }
  676.     }
  677.     else
  678.     {
  679.         wait( 0.1 );
  680.     }
  681.    
  682.     return get_zombie_point_of_interest( zombie.origin );
  683. }
  684.  
  685. get_closest_valid_player( origin, ignore_player )
  686. {
  687.     valid_player_found = false;
  688.    
  689.     players = get_players();
  690.  
  691.     if( IsDefined( ignore_player ) )
  692.     {
  693.         players = array_remove( players, ignore_player );
  694.     }
  695.  
  696.     while( !valid_player_found )
  697.     {
  698.         // find the closest player
  699.         player = GetClosest( origin, players );
  700.  
  701.         if( !isdefined( player ) )
  702.         {
  703.             return undefined;
  704.         }
  705.        
  706.         // make sure they're not a zombie or in last stand
  707.         if( !is_player_valid( player ) )
  708.         {
  709.             players = array_remove( players, player );
  710.             continue;
  711.         }
  712.         return player;
  713.     }
  714. }
  715.  
  716. is_player_valid( player )
  717. {
  718.     if( !IsDefined( player ) )
  719.     {
  720.         return false;
  721.     }
  722.  
  723.     if( !IsAlive( player ) )
  724.     {
  725.         return false;
  726.     }
  727.  
  728.     if( !IsPlayer( player ) )
  729.     {
  730.         return false;
  731.     }
  732.  
  733.     if( player.is_zombie == true )
  734.     {
  735.         return false;
  736.     }
  737.  
  738.     if( player.sessionstate == "spectator" )
  739.     {
  740.         return false;
  741.     }
  742.  
  743.     if( player.sessionstate == "intermission" )
  744.     {
  745.         return false;
  746.     }
  747.  
  748.     if(  player maps\_laststand::player_is_in_laststand() )
  749.     {
  750.         return false;
  751.     }
  752.  
  753.     if ( player isnotarget() )
  754.     {
  755.         return false;
  756.     }
  757.    
  758.     return true;
  759. }
  760.  
  761. in_revive_trigger()
  762. {
  763.     players = get_players();
  764.     for( i = 0; i < players.size; i++ )
  765.     {
  766.         if( !IsDefined( players[i] ) || !IsAlive( players[i] ) )
  767.         {
  768.             continue;
  769.         }
  770.    
  771.         if( IsDefined( players[i].revivetrigger ) )
  772.         {
  773.             if( self IsTouching( players[i].revivetrigger ) )
  774.             {
  775.                 return true;
  776.             }
  777.         }
  778.     }
  779.  
  780.     return false;
  781. }
  782.  
  783. get_closest_node( org, nodes )
  784. {
  785.     return getClosest( org, nodes );
  786. }
  787.  
  788. get_closest_2d( origin, ents )
  789. {
  790.     if( !IsDefined( ents ) )
  791.     {
  792.         return undefined;
  793.     }
  794.  
  795.     dist = Distance2d( origin, ents[0].origin );
  796.     index = 0;
  797.     for( i = 1; i < ents.size; i++ )
  798.     {
  799.         temp_dist = Distance2d( origin, ents[i].origin );
  800.         if( temp_dist < dist )
  801.         {
  802.             dist = temp_dist;
  803.             index = i;
  804.         }
  805.     }
  806.  
  807.     return ents[index];
  808. }
  809.  
  810. disable_trigger()
  811. {
  812.     if( !IsDefined( self.disabled ) || !self.disabled )
  813.     {
  814.         self.disabled = true;
  815.         self.origin = self.origin -( 0, 0, 10000 );
  816.     }
  817. }
  818.  
  819. enable_trigger()
  820. {
  821.     if( !IsDefined( self.disabled ) || !self.disabled )
  822.     {
  823.         return;
  824.     }
  825.  
  826.     self.disabled = false;
  827.     self.origin = self.origin +( 0, 0, 10000 );
  828. }
  829.  
  830. //edge_fog_start()
  831. //{
  832. //  playpoint = getstruct( "edge_fog_start", "targetname" );
  833. //
  834. //  if( !IsDefined( playpoint ) )
  835. //  {
  836. //     
  837. //  }
  838. // 
  839. //  while( isdefined( playpoint ) )
  840. //  {
  841. //      playfx( level._effect["edge_fog"], playpoint.origin );
  842. //     
  843. //      if( !isdefined( playpoint.target ) )
  844. //      {
  845. //          return;
  846. //      }
  847. //     
  848. //      playpoint = getstruct( playpoint.target, "targetname" );
  849. //  }
  850. //}
  851.  
  852.  
  853. //chris_p - fix bug with this not being an ent array!
  854. in_playable_area()
  855. {
  856.     trigger = GetEntarray( "playable_area", "targetname" );
  857.  
  858.     if( !IsDefined( trigger ) )
  859.     {
  860.         println( "No playable area trigger found! Assume EVERYWHERE is PLAYABLE" );
  861.         return true;
  862.     }
  863.    
  864.     for(i=0;i<trigger.size;i++)
  865.     {
  866.  
  867.         if( self IsTouching( trigger[i] ) )
  868.         {
  869.             return true;
  870.         }
  871.     }
  872.  
  873.     return false;
  874. }
  875.  
  876. get_random_non_destroyed_chunk( barrier_chunks )
  877. {
  878.     chunk = undefined;
  879.  
  880.     chunks = get_non_destroyed_chunks( barrier_chunks );
  881.  
  882.     if( IsDefined( chunks ) )
  883.     {
  884.         return chunks[RandomInt( chunks.size )];
  885.     }
  886.  
  887.     return undefined;
  888. }
  889.  
  890. get_closest_non_destroyed_chunk( origin, barrier_chunks )
  891. {
  892.     chunk = undefined;
  893.  
  894.     chunks = get_non_destroyed_chunks( barrier_chunks );
  895.  
  896.     if( IsDefined( chunks ) )
  897.     {
  898.         return get_closest_2d( origin, chunks );
  899.     }
  900.  
  901.     return undefined;
  902. }
  903.  
  904. get_random_destroyed_chunk( barrier_chunks )
  905. {
  906.     chunk = undefined;
  907.  
  908.     chunks = get_destroyed_chunks( barrier_chunks );
  909.  
  910.     if( IsDefined( chunks ) )
  911.     {
  912.         return chunks[RandomInt( chunks.size )];
  913.     }
  914.  
  915.     return undefined;
  916. }
  917.  
  918. get_non_destroyed_chunks( barrier_chunks )
  919. {
  920.     array = [];
  921.     for( i = 0; i < barrier_chunks.size; i++ )
  922.     {
  923.         if( !barrier_chunks[i].destroyed && !IsDefined(barrier_chunks[i].target_by_zombie) && !IsDefined(barrier_chunks[i].mid_repair) )
  924.         {
  925.             if ( barrier_chunks[i].origin == barrier_chunks[i].og_origin )
  926.             {
  927.                 array[array.size] = barrier_chunks[i];
  928.             }
  929.         }
  930.     }
  931.  
  932.     if( array.size == 0 )
  933.     {
  934.         return undefined;
  935.     }
  936.  
  937.     return array;
  938. }
  939.  
  940. get_destroyed_chunks( barrier_chunks )
  941. {
  942.     array = [];
  943.     for( i = 0; i < barrier_chunks.size; i++ )
  944.     {
  945.         if( barrier_chunks[i].destroyed  && !isdefined( barrier_chunks[i].mid_repair ) )
  946.         {
  947.             array[array.size] = barrier_chunks[i];
  948.         }
  949.     }
  950.  
  951.     if( array.size == 0 )
  952.     {
  953.         return undefined;
  954.     }
  955.  
  956.     return array;
  957. }
  958.  
  959. is_float( num )
  960. {
  961.     val = num - int( num );
  962.  
  963.     if( val != 0 )
  964.     {
  965.         return true;
  966.     }
  967.     else
  968.     {
  969.         return false;
  970.     }
  971. }
  972.  
  973. array_limiter( array, total )
  974. {
  975.     new_array = [];
  976.  
  977.     for( i = 0; i < array.size; i++ )
  978.     {
  979.         if( i < total )
  980.         {
  981.             new_array[new_array.size] = array[i];
  982.         }
  983.     }
  984.  
  985.     return new_array;
  986. }
  987.  
  988. array_validate( array )
  989. {
  990.     if( IsDefined( array ) && array.size > 0 )
  991.     {
  992.         return true;
  993.     }
  994.     else
  995.     {
  996.         return false;
  997.     }
  998. }
  999.  
  1000. add_later_round_spawners()
  1001. {
  1002.     spawners = GetEntArray( "later_round_spawners", "script_noteworthy" );
  1003.  
  1004.     for( i = 0; i < spawners.size; i++ )
  1005.     {
  1006.         add_spawner( spawners[i] );
  1007.     }
  1008. }
  1009.  
  1010. add_spawner( spawner )
  1011. {
  1012.     if( IsDefined( spawner.script_start ) && level.round_number < spawner.script_start )
  1013.     {
  1014.         return;
  1015.     }
  1016.  
  1017.     if( IsDefined( spawner.locked_spawner ) && spawner.locked_spawner )
  1018.     {
  1019.         return;
  1020.     }
  1021.  
  1022.     if( IsDefined( spawner.has_been_added ) && spawner.has_been_added )
  1023.     {
  1024.         return;
  1025.     }
  1026.  
  1027.     spawner.has_been_added = true;
  1028.  
  1029.     level.enemy_spawns[level.enemy_spawns.size] = spawner;
  1030. }
  1031.  
  1032. fake_physicslaunch( target_pos, power )
  1033. {
  1034.     start_pos = self.origin;
  1035.    
  1036.     ///////// Math Section
  1037.     // Reverse the gravity so it's negative, you could change the gravity
  1038.     // by just putting a number in there, but if you keep the dvar, then the
  1039.     // user will see it change.
  1040.     gravity = GetDvarInt( "g_gravity" ) * -1;
  1041.  
  1042.     dist = Distance( start_pos, target_pos );
  1043.    
  1044.     time = dist / power;
  1045.     delta = target_pos - start_pos;
  1046.     drop = 0.5 * gravity *( time * time );
  1047.    
  1048.     velocity = ( ( delta[0] / time ), ( delta[1] / time ), ( delta[2] - drop ) / time );
  1049.     ///////// End Math Section
  1050.  
  1051.     level thread draw_line_ent_to_pos( self, target_pos );
  1052.     self MoveGravity( velocity, time );
  1053.     return time;
  1054. }
  1055.  
  1056. //
  1057. // Spectating ===================================================================
  1058. //
  1059. add_to_spectate_list()
  1060. {
  1061.     if( !IsDefined( level.spectate_list ) )
  1062.     {
  1063.         level.spectate_list = [];
  1064.     }
  1065.  
  1066.     level.spectate_list[level.spectate_list.size] = self;
  1067. }
  1068.  
  1069. remove_from_spectate_list()
  1070. {
  1071.     if( !IsDefined( level.spectate_list ) )
  1072.     {
  1073.         return undefined;
  1074.     }
  1075.  
  1076.     level.spectate_list = array_remove( level.spectate_list, self );
  1077. }
  1078.  
  1079. get_next_from_spectate_list( ent )
  1080. {
  1081.     index = 0;
  1082.     for( i = 0; i < level.spectate_list.size; i++ )
  1083.     {
  1084.         if( ent == level.spectate_list[i] )
  1085.         {
  1086.             index = i;
  1087.         }
  1088.     }
  1089.  
  1090.     index++;
  1091.  
  1092.     if( index >= level.spectate_list.size )
  1093.     {
  1094.         index = 0;
  1095.     }
  1096.    
  1097.     return level.spectate_list[index];
  1098. }
  1099.  
  1100. get_random_from_spectate_list()
  1101. {
  1102.     return level.spectate_list[RandomInt(level.spectate_list.size)];
  1103. }
  1104.  
  1105. //
  1106. // STRINGS =======================================================================
  1107. //
  1108. add_zombie_hint( ref, text )
  1109. {
  1110.     if( !IsDefined( level.zombie_hints ) )
  1111.     {
  1112.         level.zombie_hints = [];
  1113.     }
  1114.  
  1115.     PrecacheString( text );
  1116.     level.zombie_hints[ref] = text;
  1117. }
  1118.  
  1119. get_zombie_hint( ref )
  1120. {
  1121.     if( IsDefined( level.zombie_hints[ref] ) )
  1122.     {
  1123.         return level.zombie_hints[ref];
  1124.     }
  1125.  
  1126. /#
  1127.     println( "UNABLE TO FIND HINT STRING " + ref );
  1128. #/
  1129.     return level.zombie_hints["undefined"];
  1130. }
  1131.  
  1132. // self is the trigger( usually spawned in on the fly )
  1133. // ent is the entity that has the script_hint info
  1134. set_hint_string( ent, default_ref )
  1135. {
  1136.     if( IsDefined( ent.script_hint ) )
  1137.     {
  1138.         self SetHintString( get_zombie_hint( ent.script_hint ) );
  1139.     }
  1140.     else
  1141.     {
  1142.         self SetHintString( get_zombie_hint( default_ref ) );
  1143.     }
  1144. }
  1145.  
  1146. //
  1147. // SOUNDS ===========================================================
  1148. //
  1149.  
  1150. add_sound( ref, alias )
  1151. {
  1152.     if( !IsDefined( level.zombie_sounds ) )
  1153.     {
  1154.         level.zombie_sounds = [];
  1155.     }
  1156.  
  1157.     level.zombie_sounds[ref] = alias;
  1158. }
  1159.  
  1160. play_sound_at_pos( ref, pos, ent )
  1161. {
  1162.     if( IsDefined( ent ) )
  1163.     {
  1164.         if( IsDefined( ent.script_soundalias ) )
  1165.         {
  1166.             PlaySoundAtPosition( ent.script_soundalias, pos );
  1167.             return;
  1168.         }
  1169.  
  1170.         if( IsDefined( self.script_sound ) )
  1171.         {
  1172.             ref = self.script_sound;
  1173.         }
  1174.     }
  1175.  
  1176.     if( ref == "none" )
  1177.     {
  1178.         return;
  1179.     }
  1180.  
  1181.     if( !IsDefined( level.zombie_sounds[ref] ) )
  1182.     {
  1183.         AssertMsg( "Sound \"" + ref + "\" was not put to the zombie sounds list, please use add_sound( ref, alias ) at the start of your level." );
  1184.         return;
  1185.     }
  1186.    
  1187.     PlaySoundAtPosition( level.zombie_sounds[ref], pos );
  1188. }
  1189.  
  1190. play_sound_on_ent( ref )
  1191. {
  1192.     if( IsDefined( self.script_soundalias ) )
  1193.     {
  1194.         self PlaySound( self.script_soundalias );
  1195.         return;
  1196.     }
  1197.  
  1198.     if( IsDefined( self.script_sound ) )
  1199.     {
  1200.         ref = self.script_sound;
  1201.     }
  1202.  
  1203.     if( ref == "none" )
  1204.     {
  1205.         return;
  1206.     }
  1207.  
  1208.     if( !IsDefined( level.zombie_sounds[ref] ) )
  1209.     {
  1210.         AssertMsg( "Sound \"" + ref + "\" was not put to the zombie sounds list, please use add_sound( ref, alias ) at the start of your level." );
  1211.         return;
  1212.     }
  1213.  
  1214.     self PlaySound( level.zombie_sounds[ref] );
  1215. }
  1216.  
  1217. play_loopsound_on_ent( ref )
  1218. {
  1219.     if( IsDefined( self.script_firefxsound ) )
  1220.     {
  1221.         ref = self.script_firefxsound;
  1222.     }
  1223.  
  1224.     if( ref == "none" )
  1225.     {
  1226.         return;
  1227.     }
  1228.  
  1229.     if( !IsDefined( level.zombie_sounds[ref] ) )
  1230.     {
  1231.         AssertMsg( "Sound \"" + ref + "\" was not put to the zombie sounds list, please use add_sound( ref, alias ) at the start of your level." );
  1232.         return;
  1233.     }
  1234.  
  1235.     self PlaySound( level.zombie_sounds[ref] );
  1236. }
  1237.  
  1238.  
  1239. string_to_float( string )
  1240. {
  1241.     floatParts = strTok( string, "." );
  1242.     if ( floatParts.size == 1 )
  1243.         return int(floatParts[0]);
  1244.  
  1245.     whole = int(floatParts[0]);
  1246.     decimal = int(floatParts[1]);
  1247.     while ( decimal > 1 )
  1248.         decimal *= 0.1;
  1249.  
  1250.     if ( whole >= 0 )
  1251.         return (whole + decimal);
  1252.     else
  1253.         return (whole - decimal);
  1254. }
  1255.  
  1256. //
  1257. // TABLE LOOK SECTION ============================================================
  1258. //
  1259.  
  1260. set_zombie_var( var, value, div, is_float )
  1261. {
  1262.     // First look it up in the table
  1263.     table = "mp/zombiemode.csv";
  1264.     table_value = TableLookUp( table, 0, var, 1 );
  1265.  
  1266.     if ( !IsDefined( is_float ) )
  1267.     {
  1268.         is_float = false;
  1269.     }
  1270.  
  1271.     if( IsDefined( table_value ) && table_value != "" )
  1272.     {
  1273.         if( is_float )
  1274.         {
  1275.             value = string_to_float( table_value );
  1276.         }
  1277.         else
  1278.         {
  1279.             value = int( table_value );
  1280.         }
  1281.     }
  1282.  
  1283.     if( IsDefined( div ) )
  1284.     {
  1285.         value = value / div;
  1286.     }
  1287.  
  1288.     level.zombie_vars[var] = value;
  1289. }
  1290.  
  1291. //
  1292. // DEBUG SECTION =================================================================
  1293. //
  1294. // shameless stole from austin
  1295. debug_ui()
  1296. {
  1297. /#
  1298.     wait 1;
  1299.    
  1300.     x = 510;
  1301.     y = 280;
  1302.     menu_name = "zombie debug";
  1303.  
  1304.     menu_bkg = maps\_debug::new_hud( menu_name, undefined, x, y, 1 );
  1305.     menu_bkg SetShader( "white", 160, 120 );
  1306.     menu_bkg.alignX = "left";
  1307.     menu_bkg.alignY = "top";
  1308.     menu_bkg.sort = 10;
  1309.     menu_bkg.alpha = 0.6;  
  1310.     menu_bkg.color = ( 0.0, 0.0, 0.5 );
  1311.  
  1312.     menu[0] = maps\_debug::new_hud( menu_name, "SD:",       x + 5, y + 10, 1 );
  1313.     menu[1] = maps\_debug::new_hud( menu_name, "ZH:",       x + 5, y + 20, 1 );
  1314.     menu[1] = maps\_debug::new_hud( menu_name, "ZS:",       x + 5, y + 30, 1 );
  1315.     menu[1] = maps\_debug::new_hud( menu_name, "WN:",       x + 5, y + 40, 1 );
  1316.  
  1317.     x_offset = 120;
  1318.  
  1319.     // enum
  1320.     spawn_delay          = menu.size;
  1321.     zombie_health        = menu.size + 1;
  1322.     zombie_speed         = menu.size + 2;
  1323.     round_number             = menu.size + 3;
  1324.  
  1325.     menu[spawn_delay]        = maps\_debug::new_hud( menu_name, "", x + x_offset, y + 10, 1 );
  1326.     menu[zombie_health]  = maps\_debug::new_hud( menu_name, "", x + x_offset, y + 20, 1 );
  1327.     menu[zombie_speed]   = maps\_debug::new_hud( menu_name, "", x + x_offset, y + 30, 1 );
  1328.     menu[round_number]   =  maps\_debug::new_hud( menu_name, "", x + x_offset, y + 40, 1 );
  1329.    
  1330.     while( true )
  1331.     {
  1332.         wait( 0.05 );
  1333.  
  1334.         menu[spawn_delay]       SetText( level.zombie_vars["zombie_spawn_delay"] );
  1335.         menu[zombie_health]     SetText( level.zombie_health );
  1336.         menu[zombie_speed]      SetText( level.zombie_move_speed );
  1337.         menu[round_number]      SetText( level.round_number );
  1338.     }
  1339. #/
  1340. }
  1341.  
  1342. hudelem_count()
  1343. {
  1344. /#
  1345.     max = 0;
  1346.     curr_total = 0;
  1347.     while( 1 )
  1348.     {
  1349.         if( level.hudelem_count > max )
  1350.         {
  1351.             max = level.hudelem_count;
  1352.         }
  1353.        
  1354.         println( "HudElems: " + level.hudelem_count + "[Peak: " + max + "]" );
  1355.         wait( 0.05 );
  1356.     }
  1357. #/
  1358. }
  1359.  
  1360. debug_round_advancer()
  1361. {
  1362. /#
  1363.     while( 1 )
  1364.     {
  1365.         zombs = getaiarray( "axis" );
  1366.        
  1367.         for( i = 0; i < zombs.size; i++ )
  1368.         {
  1369.             zombs[i] dodamage( zombs[i].health * 100, ( 0, 0, 0 ) );
  1370.             wait 0.5;
  1371.         }
  1372.     }  
  1373. #/
  1374. }
  1375.  
  1376. print_run_speed( speed )
  1377. {
  1378. /#
  1379.     self endon( "death" );
  1380.     while( 1 )
  1381.     {
  1382.         print3d( self.origin +( 0, 0, 64 ), speed, ( 1, 1, 1 ) );
  1383.         wait 0.05;
  1384.     }
  1385. #/
  1386. }
  1387.  
  1388. draw_line_ent_to_ent( ent1, ent2 )
  1389. {
  1390. /#
  1391.     if( GetDvarInt( "zombie_debug" ) != 1 )
  1392.     {
  1393.         return;
  1394.     }
  1395.  
  1396.     ent1 endon( "death" );
  1397.     ent2 endon( "death" );
  1398.  
  1399.     while( 1 )
  1400.     {
  1401.         line( ent1.origin, ent2.origin );
  1402.         wait( 0.05 );
  1403.     }
  1404. #/
  1405. }
  1406.  
  1407. draw_line_ent_to_pos( ent, pos, end_on )
  1408. {
  1409. /#
  1410.     if( GetDvarInt( "zombie_debug" ) != 1 )
  1411.     {
  1412.         return;
  1413.     }
  1414.  
  1415.     ent endon( "death" );
  1416.  
  1417.     ent notify( "stop_draw_line_ent_to_pos" );
  1418.     ent endon( "stop_draw_line_ent_to_pos" );
  1419.  
  1420.     if( IsDefined( end_on ) )
  1421.     {
  1422.         ent endon( end_on );
  1423.     }
  1424.  
  1425.     while( 1 )
  1426.     {
  1427.         line( ent.origin, pos );
  1428.         wait( 0.05 );
  1429.     }
  1430. #/
  1431. }
  1432.  
  1433. debug_print( msg )
  1434. {
  1435. /#
  1436.     if( GetDvarInt( "zombie_debug" ) > 0 )
  1437.     {
  1438.         println( "######### ZOMBIE: " + msg );
  1439.     }
  1440. #/
  1441. }
  1442.  
  1443. debug_blocker( pos, rad, height )
  1444. {
  1445. /#
  1446.     self notify( "stop_debug_blocker" );
  1447.     self endon( "stop_debug_blocker" );
  1448.    
  1449.     for( ;; )
  1450.     {
  1451.         if( GetDvarInt( "zombie_debug" ) != 1 )
  1452.         {
  1453.             return;
  1454.         }
  1455.  
  1456.         wait( 0.05 );
  1457.         drawcylinder( pos, rad, height );
  1458.        
  1459.     }
  1460. #/
  1461. }
  1462.  
  1463. drawcylinder( pos, rad, height )
  1464. {
  1465. /#
  1466.     currad = rad;
  1467.     curheight = height;
  1468.  
  1469.     for( r = 0; r < 20; r++ )
  1470.     {
  1471.         theta = r / 20 * 360;
  1472.         theta2 = ( r + 1 ) / 20 * 360;
  1473.  
  1474.         line( pos +( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos +( cos( theta2 ) * currad, sin( theta2 ) * currad, 0 ) );
  1475.         line( pos +( cos( theta ) * currad, sin( theta ) * currad, curheight ), pos +( cos( theta2 ) * currad, sin( theta2 ) * currad, curheight ) );
  1476.         line( pos +( cos( theta ) * currad, sin( theta ) * currad, 0 ), pos +( cos( theta ) * currad, sin( theta ) * currad, curheight ) );
  1477.     }
  1478. #/
  1479. }
  1480.  
  1481. print3d_at_pos( msg, pos, thread_endon, offset )
  1482. {
  1483. /#
  1484.     self endon( "death" );
  1485.  
  1486.     if( IsDefined( thread_endon ) )
  1487.     {
  1488.         self notify( thread_endon );
  1489.         self endon( thread_endon );
  1490.     }
  1491.  
  1492.     if( !IsDefined( offset ) )
  1493.     {
  1494.         offset = ( 0, 0, 0 );
  1495.     }
  1496.  
  1497.     while( 1 )
  1498.     {
  1499.         print3d( self.origin + offset, msg );
  1500.         wait( 0.05 );
  1501.     }
  1502. #/
  1503. }
  1504.  
  1505. debug_breadcrumbs()
  1506. {
  1507. /#
  1508.     self endon( "disconnect" );
  1509.  
  1510.     while( 1 )
  1511.     {
  1512.         if( GetDvarInt( "zombie_debug" ) != 1 )
  1513.         {
  1514.             wait( 1 );
  1515.             continue;
  1516.         }
  1517.  
  1518.         for( i = 0; i < self.zombie_breadcrumbs.size; i++ )
  1519.         {
  1520.             drawcylinder( self.zombie_breadcrumbs[i], 5, 5 );
  1521.         }
  1522.  
  1523.         wait( 0.05 );
  1524.     }
  1525. #/
  1526. }
  1527.  
  1528. debug_attack_spots_taken()
  1529. {
  1530. /#
  1531.     while( 1 )
  1532.     {
  1533.         if( GetDvarInt( "zombie_debug" ) != 2 )
  1534.         {
  1535.             wait( 1 );
  1536.             continue;
  1537.         }
  1538.  
  1539.         wait( 0.05 );
  1540.         count = 0;
  1541.         for( i = 0; i < self.attack_spots_taken.size; i++ )
  1542.         {
  1543.             if( self.attack_spots_taken[i] )
  1544.             {
  1545.                 count++;
  1546.             }
  1547.         }
  1548.  
  1549.         msg = "" + count + " / " + self.attack_spots_taken.size;
  1550.         print3d( self.origin, msg );
  1551.     }
  1552. #/
  1553. }
  1554.  
  1555. float_print3d( msg, time )
  1556. {
  1557. /#
  1558.     self endon( "death" );
  1559.  
  1560.     time = GetTime() + ( time * 1000 );
  1561.     offset = ( 0, 0, 72 );
  1562.     while( GetTime() < time )
  1563.     {
  1564.         offset = offset + ( 0, 0, 2 );
  1565.         print3d( self.origin + offset, msg, ( 1, 1, 1 ) );
  1566.         wait( 0.05 );
  1567.     }
  1568. #/
  1569. }
  1570. do_player_vo(snd, variation_count)
  1571. {
  1572.  
  1573.     /*
  1574.     index = maps\_zombiemode_weapons::get_player_index(self);  
  1575.     sound = "plr_" + index + "_" + snd;
  1576.     if(IsDefined (variation_count))
  1577.     {
  1578.         sound = sound + "_" + randomintrange(0, variation_count);
  1579.     }
  1580.     if(!isDefined(level.player_is_speaking))
  1581.     {
  1582.         level.player_is_speaking = 0;
  1583.     }
  1584.    
  1585.     if (level.player_is_speaking == 0)
  1586.     {  
  1587.         level.player_is_speaking = 1;
  1588.         self playsound(sound, "sound_done");           
  1589.         self waittill("sound_done");
  1590.         //This ensures that there is at least 3 seconds waittime before playing another VO.
  1591.         wait(2);
  1592.         level.player_is_speaking = 0;
  1593.     }  
  1594.     */
  1595. }
  1596. player_killstreak_timer()
  1597. {
  1598.     if(getdvar ("zombie_kills") == "")
  1599.     {
  1600.         setdvar ("zombie_kills", "7");
  1601.     }  
  1602.     if(getdvar ("zombie_kill_timer") == "")
  1603.     {
  1604.         setdvar ("zombie_kill_timer", "5");
  1605.     }
  1606.  
  1607.     kills = getdvarint("zombie_kills");
  1608.     time = getdvarint("zombie_kill_timer");
  1609.  
  1610.     if (!isdefined (self.timerIsrunning))  
  1611.     {
  1612.         self.timerIsrunning = 0;
  1613.     }
  1614.  
  1615.     while(1)
  1616.     {
  1617.         self waittill("zom_kill"); 
  1618.         self.killcounter ++;
  1619.  
  1620.         if (self.timerIsrunning != 1)  
  1621.         {
  1622.             self.timerIsrunning = 1;
  1623.             self thread timer_actual(kills, time);         
  1624. //          iprintlnbold ("killstreak counter started");
  1625.         }
  1626.     }  
  1627.  
  1628. }
  1629. timer_actual(kills, time)
  1630. {
  1631.  
  1632.     timer = gettime() + (time * 1000);
  1633.     while(getTime() < timer)
  1634.     {
  1635.        
  1636. //      iprintlnbold ("timer:" + (getTime() + timer * .0001));
  1637. //      iprintlnbold ("kills: " + self.killcounter);
  1638.  
  1639.         if (self.killcounter > kills)
  1640.         {
  1641.             //playsoundatposition ("ann_vox_killstreak", (0,0,0));
  1642.             //wait(3);
  1643.  
  1644.             self play_killstreak_dialog();
  1645.  
  1646. //          self thread do_player_vo("vox_killstreak", 9);
  1647.             wait(1);
  1648.        
  1649.             //resets the killcounter and the timer
  1650.             //self.killcounter = 0;
  1651.  
  1652.              timer = -1;
  1653.         }
  1654.         wait(0.1);
  1655.     }
  1656.  
  1657. //  iprintlnbold ("Timer Is Out, Resetting Kills and Time");
  1658.     self.killcounter = 0;
  1659.     self.timerIsrunning = 0;
  1660. }
  1661. play_killstreak_dialog()
  1662. {
  1663.         index = maps\_zombiemode_weapons::get_player_index(self);
  1664.         player_index = "plr_" + index + "_";   
  1665.  
  1666.         //num_variants = 12;
  1667.         waittime = 0.25;
  1668.         if(!IsDefined (self.vox_killstreak))
  1669.         {
  1670.             num_variants = maps\_zombiemode_spawner::get_number_variants(player_index + "vox_killstreak");
  1671.             self.vox_killstreak = [];
  1672.             for(i=0;i<num_variants;i++)
  1673.             {
  1674.                 self.vox_killstreak[self.vox_killstreak.size] = "vox_killstreak_" + i; 
  1675.             }
  1676.             self.vox_killstreak_available = self.vox_killstreak;
  1677.         }
  1678.         sound_to_play = random(self.vox_killstreak_available);
  1679.         self.vox_killstreak_available = array_remove(self.vox_killstreak_available,sound_to_play);
  1680.  
  1681.     //  iprintlnbold("LINE:" + player_index + sound_to_play);
  1682.  
  1683.         self do_player_killstreak_dialog(player_index, sound_to_play, waittime);
  1684.  
  1685.         //self playsound(player_index + sound_to_play, "sound_done" + sound_to_play);          
  1686.         //self waittill("sound_done" + sound_to_play);
  1687.  
  1688.         wait(waittime);
  1689.         if (self.vox_killstreak_available.size < 1 )
  1690.         {
  1691.             self.vox_killstreak_available = self.vox_killstreak;
  1692.         }
  1693.         //This ensures that there is at least 3 seconds waittime before playing another VO.
  1694.  
  1695. }
  1696. do_player_killstreak_dialog(player_index, sound_to_play, waittime)
  1697. {
  1698.     /*
  1699.     if(!IsDefined(level.player_is_speaking))
  1700.     {
  1701.         level.player_is_speaking = 0;
  1702.     }
  1703.     if(level.player_is_speaking != 1)
  1704.     {
  1705.         level.player_is_speaking = 1;
  1706.         self playsound(player_index + sound_to_play, "sound_done" + sound_to_play);        
  1707.         self waittill("sound_done" + sound_to_play);
  1708.         wait(waittime);    
  1709.         level.player_is_speaking = 0;
  1710.     }
  1711.     */
  1712. }
  1713.  
  1714. is_magic_bullet_shield_enabled( ent )
  1715. {
  1716.     if( !IsDefined( ent ) )
  1717.         return false;
  1718.  
  1719.     return ( IsDefined( ent.magic_bullet_shield ) && ent.magic_bullet_shield == true );
  1720. }
  1721.  
  1722. enemy_is_dog()
  1723. {
  1724.     return ( self.type == "dog" );
  1725. }
  1726.  
  1727.  
  1728. really_play_2D_sound(sound)
  1729. {
  1730.     temp_ent = spawn("script_origin", (0,0,0));
  1731.     temp_ent playsound (sound, sound + "wait");
  1732.     temp_ent waittill (sound + "wait");
  1733.     wait(0.05);
  1734.     temp_ent delete(); 
  1735.  
  1736. }
  1737.  
  1738.  
  1739. play_sound_2D(sound)
  1740. {
  1741.     level thread really_play_2D_sound(sound);
  1742.    
  1743.     /*
  1744.     if(!isdefined(level.playsound2dent))
  1745.     {
  1746.         level.playsound2dent = spawn("script_origin",(0,0,0));
  1747.     }
  1748.    
  1749.     //players=getplayers();
  1750.     level.playsound2dent playsound ( sound );
  1751.     */
  1752.     /*
  1753.     temp_ent = spawn("script_origin", (0,0,0));
  1754.     temp_ent playsound (sound, sound + "wait");
  1755.     temp_ent waittill (sound + "wait");
  1756.     wait(0.05);
  1757.     temp_ent delete(); 
  1758.     */
  1759.    
  1760.    
  1761. }
  1762.  
  1763. create_and_play_dialog( player_index, dialog_category, waittime, response )
  1764. {              
  1765.     if( !IsDefined ( self.sound_dialog ) )
  1766.     {
  1767.         self.sound_dialog = [];
  1768.         self.sound_dialog_available = [];
  1769.     }
  1770.                
  1771.     if ( !IsDefined ( self.sound_dialog[ dialog_category ] ) )
  1772.     {
  1773.         num_variants = maps\_zombiemode_spawner::get_number_variants( player_index + dialog_category );                  
  1774.         assertex( num_variants > 0, "No dialog variants found for category: " + dialog_category );
  1775.        
  1776.         for( i = 0; i < num_variants; i++ )
  1777.         {
  1778.             self.sound_dialog[ dialog_category ][ i ] = i;    
  1779.         }  
  1780.        
  1781.         self.sound_dialog_available[ dialog_category ] = [];
  1782.     }
  1783.    
  1784.     if ( self.sound_dialog_available[ dialog_category ].size <= 0 )
  1785.     {
  1786.         self.sound_dialog_available[ dialog_category ] = self.sound_dialog[ dialog_category ];
  1787.     }
  1788.  
  1789.     variation = random( self.sound_dialog_available[ dialog_category ] );
  1790.     self.sound_dialog_available[ dialog_category ] = array_remove( self.sound_dialog_available[ dialog_category ], variation );
  1791.  
  1792.     sound_to_play = dialog_category + "_" + variation;
  1793.     self maps\_zombiemode_spawner::do_player_playdialog(player_index, sound_to_play, waittime, response);
  1794. }
  1795.  
  1796. /*
  1797. setup_response_waittime( sound_to_play )
  1798. {
  1799.     level waittill( "player_vox_done" );
  1800.     level notify( "play_response_line" );
  1801. }
  1802. */
  1803.  
  1804. setup_response_line( player, index, response )
  1805. {
  1806.     if(index == 0) //DEMPSEY: Hero Nikolai, Rival Richtofen
  1807.     {
  1808.         setup_rival_hero( player, 1, 3, response );
  1809.     }
  1810.     if(index == 1) //NICKOLAI: Hero Richtofen, Rival Takeo
  1811.     {      
  1812.         setup_rival_hero( player, 3, 2, response );
  1813.     }      
  1814.     if(index == 2) //TAKEO: Hero Dempsey, Rival Nickolai
  1815.     {
  1816.         setup_rival_hero( player, 0, 1, response );
  1817.     }
  1818.     if(index == 3) //RICHTOFEN: Hero Nickolai, Rival Dempsey
  1819.     {
  1820.         setup_rival_hero( player, 2, 0, response );
  1821.     }
  1822.     return;
  1823. }
  1824.  
  1825. setup_rival_hero( player, hero, rival, response )
  1826. {
  1827.     players = getplayers();
  1828.  
  1829.     playHero = isdefined(players[hero]);
  1830.     playRival = isdefined(players[rival]);
  1831.    
  1832.     if(playHero && playRival)
  1833.     {
  1834.         if(randomfloatrange(0,1) < .5)
  1835.         {
  1836.             playRival = false;
  1837.         }
  1838.         else
  1839.         {
  1840.             playHero = false;
  1841.         }
  1842.     }  
  1843.     if( playHero )
  1844.     {      
  1845.         if( distancesquared (player.origin, players[hero].origin) < 500*500)
  1846.         {
  1847.             plr = "plr_" + hero + "_";
  1848.             players[hero] create_and_play_responses( plr, "vox_hr_" + response, 0.25 );
  1849.         }
  1850.         else
  1851.         {
  1852.             if(isdefined( players[rival] ) )
  1853.             {
  1854.                 playRival = true;
  1855.             }
  1856.         }
  1857.     }      
  1858.     if( playRival )
  1859.     {
  1860.         if( distancesquared (player.origin, players[rival].origin) < 500*500)
  1861.         {
  1862.             plr = "plr_" + rival + "_";
  1863.             players[rival] create_and_play_responses( plr, "vox_riv_" + response, 0.25 );
  1864.         }
  1865.     }
  1866. }
  1867.  
  1868. create_and_play_responses( player_index, dialog_category, waittime )
  1869. {              
  1870.     if( !IsDefined ( self.sound_dialog ) )
  1871.     {
  1872.         self.sound_dialog = [];
  1873.         self.sound_dialog_available = [];
  1874.     }
  1875.                
  1876.     if ( !IsDefined ( self.sound_dialog[ dialog_category ] ) )
  1877.     {
  1878.         num_variants = maps\_zombiemode_spawner::get_number_variants( player_index + dialog_category );                  
  1879.         assertex( num_variants > 0, "No dialog variants found for category: " + dialog_category );
  1880.        
  1881.         for( i = 0; i < num_variants; i++ )
  1882.         {
  1883.             self.sound_dialog[ dialog_category ][ i ] = i;    
  1884.         }  
  1885.        
  1886.         self.sound_dialog_available[ dialog_category ] = [];
  1887.     }
  1888.    
  1889.     if ( self.sound_dialog_available[ dialog_category ].size <= 0 )
  1890.     {
  1891.         self.sound_dialog_available[ dialog_category ] = self.sound_dialog[ dialog_category ];
  1892.     }
  1893.  
  1894.     variation = random( self.sound_dialog_available[ dialog_category ] );
  1895.     self.sound_dialog_available[ dialog_category ] = array_remove( self.sound_dialog_available[ dialog_category ], variation );
  1896.  
  1897.     sound_to_play = dialog_category + "_" + variation;
  1898.     self maps\_zombiemode_spawner::do_player_playdialog(player_index, sound_to_play, waittime);
  1899. }
  1900.  
  1901. include_weapon( weapon_name, in_box, weighting_func )
  1902. {
  1903.     if( !isDefined( in_box ) )
  1904.     {
  1905.         in_box = true;
  1906.     }
  1907.     maps\_zombiemode_weapons::include_zombie_weapon( weapon_name, in_box, weighting_func );
  1908. }
  1909.  
  1910. include_powerup( powerup_name )
  1911. {
  1912.     maps\_zombiemode_powerups::include_zombie_powerup( powerup_name );
  1913. }
  1914.  
  1915. include_achievement( achievement, var1, var2, var3, var4 )
  1916. {
  1917.     maps\_zombiemode_achievement::init( achievement, var1, var2, var3, var4 );
  1918. }
  1919. achievement_notify( notify_name )
  1920. {
  1921.     self notify( notify_name );
  1922. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement