SHARE
TWEET

Untitled

a guest Jun 15th, 2013 63 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include maps\mp\_utility;
  2. #include maps\mp\gametypes\_hud_util;
  3. #include maps\mp\gametypes\waffle_util;
  4. #include common_scripts\utility;
  5.  
  6. precachehelicopter(model,type)
  7. {
  8.         if(!isdefined(type))
  9.                 type = "blackhawk";
  10.  
  11.         deathfx = loadfx ("explosions/tanker_explosion");
  12.        
  13.         precacheModel( model );
  14.         level.vehicle_deathmodel[model] = model;
  15.        
  16.         //precachevehicle(type);
  17.         precacheitem( "cobra_FFAR_mp" );
  18.         precacheitem( "hind_FFAR_mp" );
  19.         precacheitem( "cobra_20mm_mp" );
  20.        
  21.         /******************************************************/
  22.         /*                                      SETUP WEAPON TAGS                                 */
  23.         /******************************************************/
  24.        
  25.         level.cobra_missile_models = [];
  26.         level.cobra_missile_models["cobra_Hellfire"] = "projectile_hellfire_missile";
  27. //      level.cobra_missile_models["cobra_Sidewinder"] = "projectile_sidewinder_missile";
  28.  
  29.         precachemodel( level.cobra_missile_models["cobra_Hellfire"] );
  30. //      precachemodel( level.cobra_missile_models["cobra_Sidewinder"] );
  31.        
  32.         // helicopter sounds:
  33.         level.heli_sound["allies"]["hit"] = "cobra_helicopter_hit";
  34.         level.heli_sound["allies"]["hitsecondary"] = "cobra_helicopter_secondary_exp";
  35.         level.heli_sound["allies"]["damaged"] = "cobra_helicopter_damaged";
  36.         level.heli_sound["allies"]["spinloop"] = "cobra_helicopter_dying_loop";
  37.         level.heli_sound["allies"]["spinstart"] = "cobra_helicopter_dying_layer";
  38.         level.heli_sound["allies"]["crash"] = "cobra_helicopter_crash";
  39.         level.heli_sound["allies"]["missilefire"] = "weap_cobra_missile_fire";
  40.         level.heli_sound["axis"]["hit"] = "hind_helicopter_hit";
  41.         level.heli_sound["axis"]["hitsecondary"] = "hind_helicopter_secondary_exp";
  42.         level.heli_sound["axis"]["damaged"] = "hind_helicopter_damaged";
  43.         level.heli_sound["axis"]["spinloop"] = "hind_helicopter_dying_loop";
  44.         level.heli_sound["axis"]["spinstart"] = "hind_helicopter_dying_layer";
  45.         level.heli_sound["axis"]["crash"] = "hind_helicopter_crash";
  46.         level.heli_sound["axis"]["missilefire"] = "weap_hind_missile_fire";
  47. }
  48.  
  49.  
  50. init()
  51. {
  52. //      precacheitem("cobra_mp");
  53. //      heli_trig = getent( "heli_obj", "targetname" );
  54. //      if ( !isdefined( heli_trig ) )
  55. //              return;
  56.        
  57.         path_start = getentarray( "heli_start", "targetname" );                 // start pointers, point to the actual start node on path
  58.         loop_start = getentarray( "heli_loop_start", "targetname" );    // start pointers for loop path in the map
  59.  
  60.         if ( !path_start.size && !loop_start.size)
  61.                 return;
  62.                
  63.         precachehelicopter( "vehicle_cobra_helicopter_fly" );
  64.         precachehelicopter( "vehicle_mi24p_hind_desert" );
  65.         precachemodel("weapon_ac130_projectile");
  66.         // array of paths, each element is an array of start nodes that all leads to a single destination node
  67.         level.chopper = undefined;
  68.         level.heli_paths = [];
  69.         level.heli_loop_paths = [];
  70.         level.heli_leavenodes = [];
  71.         level.heli_crash_paths = [];
  72.        
  73.         //dvars
  74.         thread heli_update_global_dvars();
  75.         thread onPlayerConnect();
  76. //      thread maps\mp\_ac130::init();
  77.         // helicopter fx
  78.         level.chopper_fx["explode"]["death"] = loadfx ("explosions/helicopter_explosion_cobra");
  79.         level.chopper_fx["explode"]["large"] = loadfx ("explosions/aerial_explosion_large");
  80.         level.chopper_fx["explode"]["medium"] = loadfx ("explosions/aerial_explosion");
  81.         level.chopper_fx["smoke"]["trail"] = loadfx ("smoke/smoke_trail_white_heli");
  82.         level.chopper_fx["fire"]["trail"]["medium"] = loadfx ("smoke/smoke_trail_black_heli");
  83.         level.chopper_fx["fire"]["trail"]["large"] = loadfx ("fire/fire_smoke_trail_L");
  84.         heli_path_graph();
  85.  
  86. }
  87. onPlayerConnect()
  88. {
  89.         for(;;)
  90.         {
  91.                 level waittill("connected", player);
  92. //              player thread givehelionfrag();
  93.         }
  94. }
  95. givehelionfrag()
  96. {
  97.         while(1)
  98.         {
  99.                 wait 0.05;
  100.                 if( self fragbuttonpressed() )
  101.                 {
  102.                         destination = 0;
  103.                         random_path = randomint( level.heli_paths[destination].size );
  104.                         startnode = level.heli_paths[destination][random_path];
  105.                         thread maps\mp\_helicopter::heli_think( self, startnode, self.pers["team"] );
  106.                         break;
  107.                 }
  108.         }
  109. }
  110. // update helicopter dvars realtime
  111. heli_update_global_dvars()
  112. {
  113.         for( ;; )
  114.         {
  115.                 // heli_update_dvar( dvar, default ) returns value
  116.                 level.heli_loopmax = heli_get_dvar_int( "scr_heli_loopmax", "1" );                      // how many times helicopter will circle the map before it leaves
  117.                 level.heli_missile_rof = heli_get_dvar_int( "scr_heli_missile_rof", "5" );      // missile rate of fire, one every this many seconds per target, could fire two at the same time to different targets
  118.                 level.heli_armor = heli_get_dvar_int( "scr_heli_armor", "500" );                        // armor points, after this much damage is taken, helicopter is easily damaged, and health degrades
  119.                 level.heli_rage_missile = heli_get_dvar( "scr_heli_rage_missile", "5" );        // higher the value, more frequent the missile assault
  120.                 level.heli_maxhealth = heli_get_dvar_int( "scr_heli_maxhealth", "1100" );       // max health of the helicopter
  121.                 level.heli_missile_max = heli_get_dvar_int( "scr_heli_missile_max", "3" );      // max number of missiles helicopter can carry
  122.                 level.heli_dest_wait = heli_get_dvar_int( "scr_heli_dest_wait", "2" );          // time helicopter waits (hovers) after reaching a destination
  123.                 level.heli_debug = heli_get_dvar_int( "scr_heli_debug", "0" );                          // debug mode, draws debugging info on screen
  124.                
  125.                 level.heli_targeting_delay = heli_get_dvar( "scr_heli_targeting_delay", "0.5" );        // targeting delay
  126.                 level.heli_turretReloadTime = heli_get_dvar( "scr_heli_turretReloadTime", "1.5" );      // mini-gun reload time
  127.                 level.heli_turretClipSize = heli_get_dvar_int( "scr_heli_turretClipSize", "40" );       // mini-gun clip size, rounds before reload
  128.                 level.heli_visual_range = heli_get_dvar_int( "scr_heli_visual_range", "3500" );         // distance radius helicopter will acquire targets (see)
  129.                 level.heli_health_degrade = heli_get_dvar_int( "scr_heli_health_degrade", "0" );        // health degradation after injured, health descrease per second for heavy injury, half for light injury
  130.                                
  131.                 level.heli_target_spawnprotection = heli_get_dvar_int( "scr_heli_target_spawnprotection", "5" );// players are this many seconds safe from helicopter after spawn
  132.                 level.heli_turret_engage_dist = heli_get_dvar_int( "scr_heli_turret_engage_dist", "1000" );             // engaging distance for turret
  133.                 level.heli_missile_engage_dist = heli_get_dvar_int( "scr_heli_missile_engage_dist", "2000" );   // engaging distance for missiles
  134.                 level.heli_missile_regen_time = heli_get_dvar( "scr_heli_missile_regen_time", "10" );                   // gives one more missile to helicopter every interval - seconds
  135.                 level.heli_turret_spinup_delay = heli_get_dvar( "scr_heli_turret_spinup_delay", "0.75" );                       // seconds it takes for the helicopter mini-gun to spin up before shots fired
  136.                 level.heli_target_recognition = heli_get_dvar( "scr_heli_target_recognition", "0.5" );                  // percentage of the player's body the helicopter sees before it labels him as a target
  137.                 level.heli_missile_friendlycare = heli_get_dvar_int( "scr_heli_missile_friendlycare", "256" );  // if friendly is within this distance of the target, do not shoot missile
  138.                 level.heli_missile_target_cone = heli_get_dvar( "scr_heli_missile_target_cone", "0.3" );                // dot product of vector target to helicopter forward, 0.5 is in 90 range, bigger the number, smaller the cone
  139.                 level.heli_armor_bulletdamage = heli_get_dvar( "scr_heli_armor_bulletdamage", "0.3" );                  // damage multiplier to bullets onto helicopter's armor
  140.                
  141.                 level.heli_attract_strength = heli_get_dvar( "scr_heli_attract_strength", "1000" );
  142.                 level.heli_attract_range = heli_get_dvar( "scr_heli_attract_range", "4096" );          
  143.                
  144.                 wait 1;
  145.         }
  146. }
  147.  
  148. heli_get_dvar_int( dvar, def )
  149. {
  150.         return int( heli_get_dvar( dvar, def ) );
  151. }
  152.  
  153. // dvar set/fetch/check
  154. heli_get_dvar( dvar, def )
  155. {
  156.         if ( getdvar( dvar ) != "" )
  157.                 return getdvarfloat( dvar );
  158.         else
  159.         {
  160.                 setdvar( dvar, def );
  161.                 return def;
  162.         }
  163. }
  164.  
  165. spawn_helicopter( owner, origin, angles, model, targetname )
  166. {
  167.         chopper = spawnHelicopter( owner, origin, angles, model, targetname );
  168.         chopper.attractor = Missile_CreateAttractorEnt( chopper, level.heli_attract_strength, level.heli_attract_range );
  169.         return chopper;
  170. }
  171. heli_path_graph()
  172. {      
  173.         // collecting all start nodes in the map to generate path arrays
  174.         path_start = getentarray( "heli_start", "targetname" );                 // start pointers, point to the actual start node on path
  175.         path_dest = getentarray( "heli_dest", "targetname" );                   // dest pointers, point to the actual dest node on path
  176.         loop_start = getentarray( "heli_loop_start", "targetname" );    // start pointers for loop path in the map
  177.         leave_nodes = getentarray( "heli_leave", "targetname" );                // points where the helicopter leaves to
  178.         crash_start = getentarray( "heli_crash_start", "targetname" );  // start pointers, point to the actual start node on crash path
  179.        
  180.         assertex( ( isdefined( path_start ) && isdefined( path_dest ) ), "Missing path_start or path_dest" );
  181.                
  182.         // for each destination, loop through all start nodes in level to populate array of start nodes that leads to this destination
  183.         for (i=0; i<path_dest.size; i++)
  184.         {
  185.                 startnode_array = [];
  186.                
  187.                 // destnode is the final destination from multiple start nodes
  188.                 destnode_pointer = path_dest[i];
  189.                 destnode = getent( destnode_pointer.target, "targetname" );
  190.                
  191.                 // for each start node, traverse to its dest., if same dest. then append to startnode_array
  192.                 for ( j=0; j<path_start.size; j++ )
  193.                 {
  194.                         toDest = false;
  195.                         currentnode = path_start[j];
  196.                         // traverse through path to dest.
  197.                         while( isdefined( currentnode.target ) )
  198.                         {
  199.                                 nextnode = getent( currentnode.target, "targetname" );
  200.                                 if ( nextnode.origin == destnode.origin )
  201.                                 {
  202.                                         toDest = true;
  203.                                         break;
  204.                                 }
  205.                                
  206.                                 // debug ==============================================================
  207.                                 debug_print3d_simple( "+", currentnode, ( 0, 0, -10 ) );
  208.                                 if( isdefined( nextnode.target ) )
  209.                                         debug_line( nextnode.origin, getent(nextnode.target, "targetname" ).origin, ( 0.25, 0.5, 0.25 ) );
  210.                                 if( isdefined( currentnode.script_delay ) )
  211.                                         debug_print3d_simple( "Wait: " + currentnode.script_delay , currentnode, ( 0, 0, 10 ) );
  212.                                        
  213.                                 currentnode = nextnode;
  214.                         }
  215.                         if ( toDest )
  216.                                 startnode_array[startnode_array.size] = getent( path_start[j].target, "targetname" ); // the actual start node on path, not start pointer
  217.                 }
  218.                 assertex( ( isdefined( startnode_array ) && startnode_array.size > 0 ), "No path(s) to destination" );
  219.                
  220.                 // load the array of start nodes that lead to this destination node into level.heli_paths array as an element
  221.                 level.heli_paths[level.heli_paths.size] = startnode_array;
  222.         }      
  223.        
  224.         // loop paths array
  225.         for (i=0; i<loop_start.size; i++)
  226.         {
  227.                 startnode = getent( loop_start[i].target, "targetname" );
  228.                 level.heli_loop_paths[level.heli_loop_paths.size] = startnode;
  229.         }
  230.         assertex( isdefined( level.heli_loop_paths[0] ), "No helicopter loop paths found in map" );
  231.        
  232.         // leave nodes
  233.         for (i=0; i<leave_nodes.size; i++)
  234.                 level.heli_leavenodes[level.heli_leavenodes.size] = leave_nodes[i];
  235.         assertex( isdefined( level.heli_leavenodes[0] ), "No helicopter leave nodes found in map" );
  236.        
  237.         // crash paths
  238.         for (i=0; i<crash_start.size; i++)
  239.         {
  240.                 crash_start_node = getent( crash_start[i].target, "targetname" );
  241.                 level.heli_crash_paths[level.heli_crash_paths.size] = crash_start_node;
  242.         }
  243.         assertex( isdefined( level.heli_crash_paths[0] ), "No helicopter crash paths found in map" );
  244. }
  245. // spawn helicopter at a start node and monitors it
  246. heli_think( owner, startnode, heli_team, requiredDeathCount )
  247. {
  248.  
  249.         heliAngles = owner.angles;
  250.         heliOrigin  = owner.origin + (0,0,2000);
  251.        
  252.         if( heli_team == "allies" )
  253.         {
  254.                 chopper = spawn_helicopter( owner, heliOrigin, heliAngles, "cobra_mp", "vehicle_cobra_helicopter_fly" );
  255.                 chopper playLoopSound( "mp_cobra_helicopter" );
  256.         }
  257.         else
  258.         {
  259.                 chopper = spawn_helicopter( owner, heliOrigin, heliAngles, "cobra_mp", "vehicle_mi24p_hind_desert" );
  260.                 chopper playLoopSound( "mp_cobra_helicopter" );
  261.         }
  262.        
  263.         chopper.requiredDeathCount = owner.deathCount;
  264.        
  265.         chopper.team = heli_team;
  266.         chopper.pers["team"] = heli_team;
  267.        
  268.         chopper.owner = owner;
  269.         owner.choppa = chopper;
  270.         owner.choppa = chopper;
  271.         chopper thread heli_existance();
  272.        
  273.         //chopper thread heli_trig_interval( level.heli_trigger, level.heli_hardpoint_timer );
  274.         if( isDefined( level.firstchopper ) )
  275.                 level.secondchopper = chopper;
  276.         else
  277.                 level.firstchopper = chopper;
  278.         if( isDefined( level.firstchopper ) && isDefined( level.secondchopper ) )
  279.                 level.chopper = chopper;
  280.         // TO DO: convert all helicopter attributes into dvars
  281.         chopper.reached_dest = false;                                           // has helicopter reached destination
  282.         chopper.maxhealth = level.heli_maxhealth;                       // max health
  283.         chopper.waittime = level.heli_dest_wait;                        // the time helicopter will stay stationary at destination
  284.         chopper.loopcount = 0;                                                          // how many times helicopter circled the map
  285.         chopper.evasive = false;                                                        // evasive manuvering
  286.         chopper.health_bulletdamageble = level.heli_armor;      // when damage taken is above this value, helicopter can be damage by bullets to its full amount
  287.         chopper.health_evasive = level.heli_armor;                      // when damage taken is above this value, helicopter performs evasive manuvering
  288.         chopper.health_low = level.heli_maxhealth*0.8;          // when damage taken is above this value, helicopter catchs on fire
  289.         chopper.targeting_delay = level.heli_targeting_delay;           // delay between per targeting scan - in seconds
  290.         chopper.primaryTarget = undefined;                                      // primary target ( player )
  291.         chopper.secondaryTarget = undefined;                            // secondary target ( player )
  292.         chopper.attacker = undefined;                                           // last player that shot the helicopter
  293.         chopper.missile_ammo = level.heli_missile_max;          // initial missile ammo
  294.         chopper.currentstate = "ok";                                            // health state
  295.         chopper.lastRocketFireTime = -1;
  296.        
  297.         chopper.angles = owner.angles;
  298.         chopper.origin = owner.origin + (0,0,1000);
  299.         owner hide();
  300.         if( owner.pers["team"] == "allies" )
  301.         {
  302.                 heli_centroid = chopper.origin + ( 0, 0, -145 );
  303.                 heli_forward_norm = anglestoforward( chopper.angles );
  304.                 heli_turret_point = heli_centroid + 110*heli_forward_norm;
  305.         }
  306.         else
  307.         {
  308.                 heli_centroid = chopper.origin + ( 0, 0, -100 );
  309.                 heli_forward_norm = anglestoforward( chopper.angles );
  310.                 heli_turret_point = heli_centroid + 120*heli_forward_norm;
  311.         }
  312.         owner setorigin( heli_turret_point );
  313.         owner.flyingheli = true;
  314.         self.zething = spawn("script_origin", owner.origin);
  315.         owner linkto( self.zething );
  316.         self.zething linkto( chopper );
  317.         chopper thread heli_fly( owner );       // fly heli to given node and continue on its path
  318.         chopper thread heli_damage_monitor();   // monitors damage
  319.         chopper thread heli_health();                   // display helicopter's health through smoke/fire
  320. }
  321.  
  322. heli_existance()
  323. {
  324.         self waittill_any( "death", "crashing", "leaving" );
  325.         level notify( "helicopter gone" );
  326. }
  327.  
  328.  
  329. // resets helicopter's motion values
  330. heli_reset()
  331. {
  332.         self clearTargetYaw();
  333.         self clearGoalYaw();
  334.         self setspeed( 60, 25 );       
  335.         self setyawspeed( 75, 45, 45 );
  336.         //self setjitterparams( (30, 30, 30), 4, 6 );
  337.         self setmaxpitchroll( 30, 30 );
  338.         self setneargoalnotifydist( 256 );
  339.         self setturningability(0.9);
  340. }
  341.  
  342. heli_wait( waittime )
  343. {
  344.         self endon ( "death" );
  345.         self endon ( "crashing" );
  346.         self endon ( "evasive" );
  347.  
  348.         //self thread heli_hover();
  349.         wait( waittime );
  350.         //heli_reset();
  351.        
  352.         //self notify( "stop hover" );
  353. }
  354.  
  355. // hover movements
  356. heli_hover()
  357. {
  358.         // stop hover when anything at all happens
  359.         self endon( "death" );
  360.         self endon( "stop hover" );
  361.         self endon( "evasive" );
  362.         self endon( "leaving" );
  363.         self endon( "crashing" );
  364.        
  365.         original_pos = self.origin;
  366.         original_angles = self.angles;
  367.         self setyawspeed( 10, 45, 45 );
  368.        
  369.         x = 0;
  370.         y = 0;
  371.        
  372.         // random hovering movement loop
  373.         /*
  374.         for( ;; )
  375.         {
  376.                 for( idx=0; idx<10; idx++ )
  377.                 {
  378.                         heli_speed = 10+randomint(10);
  379.                         heli_accel = 10+randomint(5);
  380.                         self setspeed( heli_speed, heli_accel );       
  381.                         x -= randomInt(5);
  382.                         x += randomInt(5);
  383.                         y -= randomInt(5);
  384.                         y += randomInt(5);
  385.                         self setvehgoalpos( original_pos+( x, y, randomInt(10) ), 0 );
  386.                         //self setgoalyaw( self.angles[1]+randomint(10), 45, 45 );
  387.                         self waittillmatch( "goal" );
  388.                         wait ( 1+randomInt(2) );
  389.                 }
  390.                 self setvehgoalpos( original_pos, 0 );
  391.                 //self setgoalyaw( original_angles[1], 45, 45 );
  392.                 self waittillmatch( "goal" );
  393.         }
  394.         */
  395. }
  396.  
  397. // accumulate damage and react
  398. heli_damage_monitor()
  399. {
  400.         self endon( "death" );
  401.         self endon( "crashing" );
  402.         self endon( "leaving" );
  403.        
  404.         self.damageTaken = 0;
  405. //      self thread maps\mp\gametypes\tankwarfare::watchdamage( self, 500 );
  406.         for( ;; )
  407.         {
  408.                 // this damage is done to self.health which isnt used to determine the helicopter's health, damageTaken is.
  409.                 self waittill( "damage", damage, attacker, direction_vec, P, type );
  410.                 // self notify( "damage taken" ); // not used anywhere yet
  411.                
  412.                 if( !isdefined( attacker ) || !isplayer( attacker ) )
  413.                         continue;
  414.                
  415.                 heli_friendlyfire = maps\mp\gametypes\_weapons::friendlyFireCheck( self.owner, attacker );
  416.                 // skip damage if friendlyfire is disabled
  417.                 if( !heli_friendlyfire )
  418.                         continue;
  419.  
  420.                 if(     isDefined( self.owner ) && attacker == self.owner )
  421.                         continue;
  422.                
  423.                 if ( level.teamBased )
  424.                         isValidAttacker = (isdefined( attacker.pers["team"] ) && attacker.pers["team"] != self.team);
  425.                 else
  426.                         isValidAttacker = true;
  427.  
  428.                 if ( !isValidAttacker )
  429.                         continue;
  430.  
  431.                 attacker thread maps\mp\gametypes\_damagefeedback::updateDamageFeedback( false );
  432.                 self.attacker = attacker;
  433.  
  434.                 if ( type == "MOD_RIFLE_BULLET" || type == "MOD_PISTOL_BULLET" )
  435.                 {
  436.                         if( self.damageTaken >= self.health_bulletdamageble )
  437.                                 self.damageTaken += damage;
  438.                         else
  439.                                 self.damageTaken += damage*level.heli_armor_bulletdamage;
  440.                 }
  441.                 else
  442.                         self.damageTaken += damage;
  443.                
  444.                 if( self.damageTaken > self.maxhealth )
  445.                         attacker notify( "destroyed_helicopter", self.owner );
  446.                
  447.         }
  448. }
  449.  
  450. heli_health()
  451. {
  452.         self endon( "death" );
  453.         self endon( "leaving" );
  454.         self endon( "crashing" );
  455.        
  456.         self.currentstate = "ok";
  457.         self.laststate = "ok";
  458.         self setdamagestage( 3 );
  459.        
  460.         for ( ;; )
  461.         {
  462.                 if ( self.health_bulletdamageble > self.health_low )
  463.                 {
  464.                         if ( self.damageTaken >= self.health_bulletdamageble )
  465.                                 self.currentstate = "heavy smoke";
  466.                         else if ( self.damageTaken >= self.health_low )
  467.                                 self.currentstate = "light smoke";
  468.                 }
  469.                 else
  470.                 {
  471.                         if ( self.damageTaken >= self.health_low )
  472.                                 self.currentstate = "heavy smoke";
  473.                         else if ( self.damageTaken >= self.health_bulletdamageble )
  474.                                 self.currentstate = "light smoke";
  475.                 }
  476.                
  477.                 if ( self.currentstate == "light smoke" && self.laststate != "light smoke" )
  478.                 {
  479.                         self setdamagestage( 2 );
  480.                         self.laststate = self.currentstate;
  481.  
  482.                 }
  483.                 if ( self.currentstate == "heavy smoke" && self.laststate != "heavy smoke" )
  484.                 {
  485.                         self setdamagestage( 1 );
  486.                         self notify ( "stop body smoke" );
  487.                         self.laststate = self.currentstate;
  488.                        
  489.                         // play loop sound "damaged"
  490.                         //self playloopsound ( level.heli_sound[self.team]["damaged"] );
  491.                 }
  492.                
  493.                 if ( self.currentstate == "heavy smoke" )
  494.                 {
  495.                         self.damageTaken += level.heli_health_degrade;
  496.                         level.heli_rage_missile = 20; // increase missile firing rate more
  497.                 }
  498.                 if ( self.currentstate == "light smoke" )
  499.                 {
  500.                         self.damageTaken += level.heli_health_degrade/2;
  501.                         level.heli_rage_missile = 10;   // increase missile firing rate
  502.                 }
  503.                        
  504.                 if( self.damageTaken >= self.health_evasive )
  505.                 {
  506.                         if( !self.evasive )
  507.                                 self thread heli_evasive();
  508.                 }
  509.                
  510.                 if( self.damageTaken > self.maxhealth )
  511.                         self thread heli_crash();
  512.                        
  513.                 // debug =================================
  514.                 if( self.damageTaken <= level.heli_armor )
  515.                         debug_print3d_simple( "Armor: " + (level.heli_armor-self.damageTaken), self, ( 0,0,100 ), 20 );
  516.                 else
  517.                         debug_print3d_simple( "Health: " + ( self.maxhealth - self.damageTaken ), self, ( 0,0,100 ), 20 );
  518.                        
  519.                 wait 1;
  520.         }
  521. }
  522. // evasive manuvering - helicopter circles the map for awhile then returns to path
  523. heli_evasive()
  524. {
  525.         // only one instance allowed
  526.         self notify( "evasive" );
  527.        
  528.         self.evasive = true;
  529.        
  530.         // set helicopter path to circle the map level.heli_loopmax number of times
  531.         loop_startnode = level.heli_loop_paths[0];
  532. //      self thread heli_fly( loop_startnode );
  533. }
  534.  
  535. // attach helicopter on crash path
  536. heli_crash()
  537. {
  538.         self notify( "crashing" );
  539.        
  540.         // helicopter losing control and spins
  541.         self thread heli_spin( 180 );
  542.  
  543.         // body explosion fx when on crash path
  544.         playfxontag( level.chopper_fx["explode"]["large"], self, "tag_engine_left" );
  545.         // along with a sound
  546.         self playSound ( level.heli_sound[self.team]["hitsecondary"] );
  547.  
  548.         self setdamagestage( 0 );
  549.         // form fire smoke trails on body after explosion
  550.         self thread trail_fx( level.chopper_fx["fire"]["trail"]["large"], "tag_engine_left", "stop body fire" );
  551.        
  552. //      self waittill( "destination reached" );
  553.         self thread heli_explode();
  554. }
  555.  
  556. // self spin at one rev per 2 sec
  557. heli_spin( speed )
  558. {
  559.         self endon( "death" );
  560.        
  561.         // tail explosion that caused the spinning
  562.         playfxontag( level.chopper_fx["explode"]["medium"], self, "tail_rotor_jnt" );
  563.         // play hit sound immediately so players know they got it
  564.         self playSound ( level.heli_sound[self.team]["hit"] );
  565.        
  566.         // play heli crashing spinning sound
  567.         self thread spinSoundShortly();
  568.        
  569.         // form smoke trails on tail after explosion
  570.         self thread trail_fx( level.chopper_fx["smoke"]["trail"], "tail_rotor_jnt", "stop tail smoke" );
  571.        
  572.         // spins until death
  573.         self setyawspeed( speed, speed, speed );
  574.         while ( isdefined( self ) )
  575.         {
  576.                 self settargetyaw( self.angles[1]+(speed*0.9) );
  577.                 wait ( 1 );
  578.         }
  579. }
  580.  
  581. spinSoundShortly()
  582. {
  583.         self endon("death");
  584.        
  585.         wait .25;
  586.        
  587.         self stopLoopSound();
  588.         wait .05;
  589.         self playLoopSound( level.heli_sound[self.team]["spinloop"] );
  590.         wait .05;
  591.         self playSound( level.heli_sound[self.team]["spinstart"] );
  592. }
  593.  
  594. // TO DO: Robert will replace the for-loop to use geotrails for smoke trail fx
  595. // this plays single smoke trail puff on origin per 0.05
  596. // trail_fx is the fx string, trail_tag is the tag string
  597. trail_fx( trail_fx, trail_tag, stop_notify )
  598. {
  599.         // only one instance allowed
  600.         self notify( stop_notify );
  601.         self endon( stop_notify );
  602.         self endon( "death" );
  603.                
  604.         for ( ;; )
  605.         {
  606.                 playfxontag( trail_fx, self, trail_tag );
  607.                 wait( 0.05 );
  608.         }
  609. }
  610.  
  611. // crash explosion
  612. heli_explode()
  613. {
  614.         self notify( "death" );
  615.        
  616.         forward = ( self.origin + ( 0, 0, 100 ) ) - self.origin;
  617.         playfx ( level.chopper_fx["explode"]["death"], self.origin, forward );
  618.        
  619.         // play heli explosion sound
  620.         self playSound( level.heli_sound[self.team]["crash"] );
  621.         self.owner setclientdvar( "cg_thirdpersonrange", "120" );
  622.         self.owner [[level.onSpawnPlayer]]();
  623.         self.owner maps\mp\gametypes\_class::giveLoadout(self.owner.pers["team"], self.owner.class);
  624.         self.owner show();
  625.         self.owner.flyingheli = undefined;
  626. //      if( isDefined( self.attacker ) && isPlayer( self.attacker )  && isAlive( self.attacker ) )
  627. //              self.owner thread maps\mp\gametypes\_globallogic::Callback_PlayerDamage( self.attacker, self.attacker, self.health, "MOD_SUICIDE", "", self.angles, "torso_upper", 0, 0);
  628. //      self.owner suicide();
  629.         self.owner unlink();
  630.         level.chopper = undefined;
  631.         if(isDefined(level.firstchopper ) )
  632.         {
  633.                 if( self == level.firstchopper )
  634.                         level.firstchopper = undefined;
  635.         }
  636.         if(isDefined(level.secondchopper ) )
  637.         {
  638.                 if( self == level.secondchopper )
  639.                         level.secondchopper = undefined;
  640.         }
  641.         if( isDefined( self ) )
  642.                 self delete();
  643. }
  644.  
  645.  
  646. // piloting of heli
  647. heli_fly( owner )
  648. {
  649.         self endon( "death" );
  650.        
  651.         // only one thread instance allowed
  652.         self notify( "flying");
  653.         self endon( "flying" );
  654.        
  655.         // if owner switches teams, helicopter should leave
  656.         self endon( "abandoned" );
  657.         owner takeallweapons();
  658.         self setturningability(1);
  659.         self.reached_dest = false;
  660.         heli_reset();
  661.         owner.isturretsafe = true;
  662.         owner.islinked = true;
  663.         self.ispitchedown = false;
  664.         pos = self.origin;
  665.         owner setclientdvar( "cg_thirdperson", "1" );
  666.         owner setclientdvar( "cg_thirdpersonrange", "500" );
  667. //      owner thread maps\mp\_ac130::ac130_attachPlayer( owner );
  668.         owner iprintlnbold( "You are Piloting a Helicopter, press Melee to move" );
  669.         owner iprintlnbold( "foward, and press Fire to fire The Helicopter's " );
  670.         owner iprintlnbold( "Missiles" );
  671.         wait( 2 );
  672.         while( isAlive( owner ) )
  673.         {
  674.                 angle = owner getplayerangles();
  675.                 if( owner meleebuttonpressed() )
  676.                         owner thread moveonangle(  angle );
  677.                 else
  678.                 {
  679.                         distance = vecscale( anglestoforward( angle ), 25 );
  680. //                      self setvehgoalpos( self.origin + distance, 1 );
  681.                         if( self.ispitchedown )
  682.                         {
  683.                                 self setvehgoalpos( self.origin + distance, 1 );
  684.                                 self helirotateto( (self.angles[0], self.angles[1], self.angles[2] ), "up" );
  685.                                 self.ispitchedown = false;
  686.                         }
  687.                         self.angles = owner.angles;
  688.                 }
  689.                 if( owner attackbuttonpressed() && owner.isturretsafe )
  690.                 {
  691.                         owner.isturretsafe = false;
  692.                         owner thread maketurretsafe();
  693.                         owner thread firemissile( angle );
  694.                 }
  695.                 if( owner fragbuttonpressed() )
  696.                 {
  697.                         owner heli_vertical( "down" );
  698.                 }
  699.                 if( owner SecondaryOffhandButtonPressed() )
  700.                 {
  701.                         owner heli_vertical( "up" );
  702.                 }
  703.                 self.angles = angle;
  704.                 wait 0.05;
  705.         }
  706. }
  707. helirotateto( vec, dif )
  708. {
  709.         if( dif == "up" )
  710.         {
  711.                 for( i = 0; i < 10; i++ )
  712.                 {
  713.                         self.angles = self.angles + ( 1.5,0,0 );
  714.                         wait 0.05;
  715.                 }
  716.         }
  717.         else
  718.         {
  719.                 for( i = 0; i < 10; i++ )
  720.                 {
  721.                         self.angles = self.angles - ( 1.5,0,0 );
  722.                         wait 0.05;
  723.                 }
  724.         }
  725. }
  726. heli_vertical( dir )
  727. {
  728.         if( dir == "up" )
  729.         {
  730.                 if( bullettracepassed( self.choppa.origin,  self.choppa.origin + (0,0,25), false, self.choppa ) )
  731.                 {
  732.                         self.choppa setspeed( 100, 100 );      
  733.                         self.choppa setvehgoalpos( self.choppa.origin + (0,0,50), 1 );
  734.                 }
  735.                 else
  736.                 {
  737.                         self iprintlnbold("You Crashed your helicopter, try to");
  738.                         self iprintlnbold("keep a little bit higher next time.");
  739.                         self.choppa thread heli_explode();
  740.                 }
  741.         }
  742.         else
  743.         {
  744.                 if( bullettracepassed( self.choppa.origin,  self.choppa.origin - (0,0,25), false, self.choppa ) )
  745.                 {
  746.                         self.choppa setspeed( 100, 100 );      
  747.                         self.choppa setvehgoalpos( self.choppa.origin - (0,0,50), 1 );
  748.                 }
  749.                 else
  750.                 {
  751.                         self iprintlnbold("You Crashed your helicopter, try to");
  752.                         self iprintlnbold("keep a little bit higher next time.");
  753.                         self.choppa thread heli_explode();
  754.                 }
  755.         }
  756. }
  757. firemissile( angle )//pshh weapons, script controlled missiles are way better
  758. {//                                                                     my hatred of weapon files is quite evident in this script
  759.         missile = spawn( "script_model", self.origin );
  760.         vec = vecscale( anglestoforward( angle ), 10000000 );
  761.         vec2 = vecscale( anglestoforward( angle ), 15 );
  762.         trace = bullettrace( self.origin + vec2, self.origin + vec, true, self.choppa );
  763.         pos = trace["position"];
  764.         time = distance( self.origin, pos) / 6500;
  765. //      time = 10;
  766.         missile setmodel("projectile_rpg7");
  767.         missile.angles = vectortoangles( pos - missile.origin );
  768.         self playsound( "heli_fire" );
  769.         missile moveto( pos, time );
  770.         playfxontag( level.fx_airstrike_contrail, missile, "tag_fx" );
  771.         wait time;
  772.         RadiusDamage( missile.origin, 350, 500, 25, self );
  773.         playfx( level.chopper_fx["explode"]["medium"], missile.origin );
  774.         missile hide();
  775.         missile delete();
  776. }
  777.  
  778.  
  779. maketurretsafe()
  780. {
  781.         wait 1;
  782.         self.isturretsafe = true;
  783. }
  784.  
  785.  
  786. moveonangle( angle )
  787. {
  788.         distance = vecscale( anglestoforward( angle ), 25 );
  789.         if( bullettracepassed( self.origin, self.origin + distance, false, self.choppa ) )
  790.         {
  791.                 if( !isDefined( self.choppa ) )
  792.                         return;
  793.                 if( !self.choppa.ispitchedown )
  794.                 {
  795. //                      self.choppa rotateto( (self.angles[0] - 15, self.angles[1], self.angles[2] ), 0.5 );
  796.                         self helirotateto( (0,0,0), "down" );
  797.                         self.choppa.ispitchedown = true;
  798.                 }
  799. //              self.zething moveto( self.choppa.origin + distance, 0.1);
  800. //              wait 0.1;
  801.                 self.choppa setspeed( 50, 50 );
  802.                 self.choppa SetTargetYaw( angle[1] );
  803.                 self.choppa SetYawSpeed( 180, 60, 60, 0 );
  804. //              self.targetent.origin = self.choppa.origin + distance;
  805. //              if( isDefined( self.choppa ) )
  806.                         self.choppa setvehgoalpos( self.choppa.origin + distance, 0 );
  807.         }
  808.         else
  809.         {
  810.                 self iprintlnbold("You Crashed your helicopter, try to");
  811.                 self iprintlnbold("keep a little bit higher next time.");
  812.                 self.choppa thread heli_explode();
  813.         }
  814. }
  815. shootingposition()
  816. {
  817.         self.choppa setvehgoalpos( self.choppa.origin, 0 );
  818.         self.choppa clearTargetYaw();
  819.         self.choppa clearGoalYaw();
  820.         oldorigin = self.origin;
  821.         oldangle = self.angles;
  822.         self giveweapon( "helicopter_mp" );
  823.         self switchtoweapon( "helicopter_mp" );
  824.         wait 2;
  825.         while(1)
  826.         {
  827.                 wait 0.05;
  828.                 if( self usebuttonpressed() )
  829.                         break;
  830.         }
  831.         self setorigin( oldorigin );
  832.         self setplayerangles( oldangle );
  833.         self takeweapon( "helicopter_mp" );
  834. }
  835.  
  836. check_owner()
  837. {
  838.         if ( !isdefined( self.owner ) || !isdefined( self.owner.pers["team"] ) || self.owner.pers["team"] != self.team )
  839.         {
  840.                 self notify ( "abandoned" );
  841.                 self thread heli_explode();    
  842.         }
  843. }
  844.  
  845.  
  846. // debug on screen elements ===========================================================
  847. debug_print_target()
  848. {
  849.         if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
  850.         {
  851.                 // targeting debug print
  852.                 if( isdefined( self.primaryTarget ) && isdefined( self.primaryTarget.threatlevel ) )
  853.                         primary_msg = "Primary: " + self.primaryTarget.name + " : " + self.primaryTarget.threatlevel;
  854.                 else
  855.                         primary_msg = "Primary: ";
  856.                        
  857.                 if( isdefined( self.secondaryTarget ) && isdefined( self.secondaryTarget.threatlevel ) )
  858.                         secondary_msg = "Secondary: " + self.secondaryTarget.name + " : " + self.secondaryTarget.threatlevel;
  859.                 else
  860.                         secondary_msg = "Secondary: ";
  861.                        
  862.                 frames = int( self.targeting_delay*20 )+1;
  863.                
  864.                 thread draw_text( primary_msg, (1, 0.6, 0.6), self, ( 0, 0, 40), frames );
  865.                 thread draw_text( secondary_msg, (1, 0.6, 0.6), self, ( 0, 0, 0), frames );
  866.         }
  867. }
  868.  
  869. debug_print3d( message, color, ent, origin_offset, frames )
  870. {
  871.         if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
  872.                 self thread draw_text( message, color, ent, origin_offset, frames );
  873. }
  874.  
  875. debug_print3d_simple( message, ent, offset, frames )
  876. {
  877.         if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
  878.         {
  879.                 if( isdefined( frames ) )
  880.                         thread draw_text( message, ( 0.8, 0.8, 0.8 ), ent, offset, frames );
  881.                 else
  882.                         thread draw_text( message, ( 0.8, 0.8, 0.8 ), ent, offset, 0 );
  883.         }
  884. }
  885.  
  886. debug_line( from, to, color, frames )
  887. {
  888.         if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 && !isdefined( frames ) )
  889.         {
  890.                 thread draw_line( from, to, color );
  891.         }
  892.         else if ( isdefined( level.heli_debug ) && level.heli_debug == 1.0 )
  893.                 thread draw_line( from, to, color, frames);
  894. }
  895.  
  896. draw_text( msg, color, ent, offset, frames )
  897. {
  898.         //level endon( "helicopter gone" );
  899.         if( frames == 0 )
  900.         {
  901.                 while ( isdefined( ent ) )
  902.                 {
  903.                         print3d( ent.origin+offset, msg , color, 0.5, 4 );
  904.                         wait 0.05;
  905.                 }
  906.         }
  907.         else
  908.         {
  909.                 for( i=0; i < frames; i++ )
  910.                 {
  911.                         if( !isdefined( ent ) )
  912.                                 break;
  913.                         print3d( ent.origin+offset, msg , color, 0.5, 4 );
  914.                         wait 0.05;
  915.                 }
  916.         }
  917. }
  918.  
  919. draw_line( from, to, color, frames )
  920. {
  921.         //level endon( "helicopter gone" );
  922.         if( isdefined( frames ) )
  923.         {
  924.                 for( i=0; i<frames; i++ )
  925.                 {
  926.                         line( from, to, color );
  927.                         wait 0.05;
  928.                 }              
  929.         }
  930.         else
  931.         {
  932.                 for( ;; )
  933.                 {
  934.                         line( from, to, color );
  935.                         wait 0.05;
  936.                 }
  937.         }
  938. }
  939.  
  940. // cpu friendly version of sight cone trace performs single trace per frame
  941. // 1/4 second delay
  942. improved_sightconetrace( helicopter )
  943. {
  944.         // obtain start as origin of the turret point
  945.         heli_centroid = helicopter.origin + ( 0, 0, -160 );
  946.         heli_forward_norm = anglestoforward( helicopter.angles );
  947.         heli_turret_point = heli_centroid + 144*heli_forward_norm;
  948.         draw_line( heli_turret_point, self.origin, ( 1, 1, 1 ), 5 );
  949.         start = heli_turret_point;
  950.         yes = 0;
  951.         point = [];
  952.        
  953.         for( i=0; i<5; i++ )
  954.         {
  955.                 if( !isdefined( self ) )
  956.                         break;
  957.                
  958.                 half_height = self.origin+(0,0,36);
  959.                
  960.                 tovec = start - half_height;
  961.                 tovec_angles = vectortoangles(tovec);
  962.                 forward_norm = anglestoforward(tovec_angles);
  963.                 side_norm = anglestoright(tovec_angles);
  964.  
  965.                 point[point.size] = self.origin + (0,0,36);
  966.                 point[point.size] = self.origin + side_norm*(15, 15, 0) + (0, 0, 10);
  967.                 point[point.size] = self.origin + side_norm*(-15, -15, 0) + (0, 0, 10);
  968.                 point[point.size] = point[2]+(0,0,64);
  969.                 point[point.size] = point[1]+(0,0,64);
  970.                
  971.                 // debug =====================================
  972.                 draw_line( point[1], point[2], (1, 1, 1), 1 );
  973.                 draw_line( point[2], point[3], (1, 1, 1), 1 );
  974.                 draw_line( point[3], point[4], (1, 1, 1), 1 );
  975.                 draw_line( point[4], point[1], (1, 1, 1), 1 );
  976.                
  977.                 if( bullettracepassed( start, point[i], true, self ) )
  978.                 {
  979.                         draw_line( start, point[i], (randomInt(10)/10, randomInt(10)/10, randomInt(10)/10), 1 );
  980.                         yes++;
  981.                 }
  982.                 waittillframeend;
  983.                 //wait 0.05;
  984.         }
  985.         //println( "Target sight: " + yes/5 );
  986.         return yes/5;
  987. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top