daily pastebin goal
4%
SHARE
TWEET

Untitled

a guest Feb 22nd, 2019 60 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 common_scripts\utility;
  4. init()
  5. {
  6.    precacheModel( "jokers_stealth" );
  7.    
  8.  //  level.scr_stealthbomber_height = getdvarx( "scr_stealthbomber_height", "int", 1000, -10000, 50000 );
  9.    
  10.    level.bomberfx = loadfx ("explosions/clusterbomb");
  11.    level.bombeffect = loadfx ("explosions/artilleryExp_dirt_brown");
  12.    level.bombstrike = loadfx ("explosions/wall_explosion_pm_a");
  13.    level.fx_airstrike_contrail = loadfx ("smoke/smoke_geotrail_javelin");
  14.    
  15.    game["dialog"]["airstrike_inbound"] = "airstrike_friendly";
  16.    game["dialog"]["enemy_airstrike_inbound"] = "airstrike_enemy";
  17. }
  18. distance2d(a,b)
  19. {
  20.    return distance((a[0],a[1],0), (b[0],b[1],0));
  21. }
  22.  
  23. doBomb(origin, owner, team)
  24. {
  25.    num = 17 + randomint(3);
  26.    
  27.    level.bomberInProgress = true;
  28.    trace = bullettrace(origin, origin + (0,0,-10000), false, undefined);
  29.    targetpos = trace["position"];
  30.    
  31.    yaw = getBestBomberDirection( targetpos );
  32.    
  33.    team = self.pers["team"];
  34.    otherTeam = level.otherTeam[team];
  35.    
  36.    if ( level.teambased )
  37.    {
  38.       players = level.players;
  39.       if ( !level.hardcoreMode )
  40.       {
  41.          for(i = 0; i < players.size; i++)
  42.          {
  43.             if(isalive(players[i]) && (isdefined(players[i].pers["team"])) && (players[i].pers["team"] == team))
  44.             {
  45.                if ( pointIsInAirstrikeArea( players[i].origin, targetpos, yaw ) )
  46.                   players[i] iprintlnbold(&"STEALTH BOMBERS Near Your Position");
  47.             }
  48.          }
  49.       }
  50.      
  51.       maps\mp\gametypes\_globallogic::leaderDialog( "airstrike_inbound", team );
  52.       maps\mp\gametypes\_globallogic::leaderDialog( "enemy_airstrike_inbound", otherteam );  
  53.       for ( i = 0; i < level.players.size; i++ )
  54.       {
  55.          player = level.players[i];
  56.          playerteam = player.pers["team"];
  57.          if ( isdefined( playerteam ) )
  58.          {
  59.             if ( playerteam == team )
  60.                player iprintln( &"STEALTH BOMBERS Ready to Deploy", owner );
  61.          }
  62.       }
  63.    }
  64.    else
  65.    {
  66.       owner maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "airstrike_inbound" );
  67.       /*
  68.       for ( i = 0; i < level.players.size; i++ )
  69.       {
  70.          if ( level.players[i] != owner && isDefined( level.players[i].team ) )
  71.             level.players[i] maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "enemy_airstrike_inbound" );
  72.       }
  73.       */
  74.  
  75.       if ( !level.hardcoreMode )
  76.       {
  77.          if ( pointIsInAirstrikeArea( owner.origin, targetpos, yaw ) )
  78.             owner iprintlnbold(&"STEALTH BOMBERS Near Your Position");
  79.       }
  80.    }
  81.    
  82.    wait 2;
  83.  
  84.    if ( !isDefined( owner ) )
  85.    {
  86.       level.bomberInProgress = undefined;
  87.       return;
  88.    }
  89.    
  90.    owner notify ( "begin_airstrike" );
  91.    
  92.    dangerCenter = spawnstruct();
  93.    dangerCenter.origin = targetpos;
  94.    dangerCenter.forward = anglesToForward( (0,yaw,0) );
  95.    level.artilleryDangerCenters[ level.artilleryDangerCenters.size ] = dangerCenter;
  96.    /# level thread debugArtilleryDangerCenters(); #/
  97.    
  98.    wait 1;
  99.    callBomber( owner, targetpos, yaw );
  100.    wait 1;
  101.    callBomber( owner, targetpos + anglestoright( (0,yaw,0) )*500, yaw );
  102.    wait 2;
  103.    callBomber( owner, targetpos - anglestoright ( (0, yaw, 0) )*500, yaw );
  104.      
  105.    found = false;
  106.    newarray = [];
  107.    for ( i = 0; i < level.artilleryDangerCenters.size; i++ )
  108.    {
  109.       if ( !found && level.artilleryDangerCenters[i].origin == targetpos )
  110.       {
  111.          found = true;
  112.          continue;
  113.       }
  114.      
  115.       newarray[ newarray.size ] = level.artilleryDangerCenters[i];
  116.    }
  117.    assert( found );
  118.    assert( newarray.size == level.artilleryDangerCenters.size - 1 );
  119.    level.artilleryDangerCenters = newarray;
  120.  
  121.    level.bomberInProgress = undefined;
  122. }
  123.  
  124. getAirstrikeDanger( point )
  125. {
  126.    danger = 0;
  127.    for ( i = 0; i < level.artilleryDangerCenters.size; i++ )
  128.    {
  129.       origin = level.artilleryDangerCenters[i].origin;
  130.       forward = level.artilleryDangerCenters[i].forward;
  131.      
  132.       danger += getSingleAirstrikeDanger( point, origin, forward );
  133.    }
  134.    return danger;
  135. }
  136.  
  137. getSingleAirstrikeDanger( point, origin, forward )
  138. {
  139.    center = origin + level.artilleryDangerForwardPush * level.artilleryDangerMaxRadius * forward;
  140.    
  141.    diff = point - center;
  142.    diff = (diff[0], diff[1], 0);
  143.    
  144.    forwardPart = vectorDot( diff, forward ) * forward;
  145.    perpendicularPart = diff - forwardPart;
  146.    
  147.    circlePos = perpendicularPart + forwardPart / level.artilleryDangerOvalScale;
  148.    
  149.    /* /#
  150.    if ( getdvar("scr_airstrikedebug") == "1" )
  151.    {
  152.       thread airstrikeLine( center, center + perpendicularPart, (1,1,1), 30 );
  153.       thread airstrikeLine( center + perpendicularPart, center + circlePos, (1,1,1), 30 );
  154.       thread airstrikeLine( center + circlePos, point, (.5,.5,.5), 30 );
  155.    }
  156.    #/ */
  157.    
  158.    distsq = lengthSquared( circlePos );
  159.    
  160.    if ( distsq > level.artilleryDangerMaxRadius * level.artilleryDangerMaxRadius )
  161.       return 0;
  162.    
  163.    if ( distsq < level.artilleryDangerMinRadius * level.artilleryDangerMinRadius )
  164.       return 1;
  165.    
  166.    dist = sqrt( distsq );
  167.    distFrac = (dist - level.artilleryDangerMinRadius) / (level.artilleryDangerMaxRadius - level.artilleryDangerMinRadius);
  168.    
  169.    assertEx( distFrac >= 0 && distFrac <= 1, distFrac );
  170.    
  171.    return 1 - distFrac;
  172. }
  173.  
  174. pointIsInAirstrikeArea( point, targetpos, yaw )
  175. {
  176.    return distance2d( point, targetpos ) <= level.artilleryDangerMaxRadius * 1.25;
  177. }
  178.  
  179. losRadiusDamage(pos, radius, max, min, owner, eInflictor)
  180. {
  181.    ents = maps\mp\gametypes\_weapons::getDamageableEnts(pos, radius, true);
  182.  
  183.    for (i = 0; i < ents.size; i++)
  184.    {
  185.       if (ents[i].entity == self)
  186.          continue;
  187.      
  188.       dist = distance(pos, ents[i].damageCenter);
  189.      
  190.       if ( ents[i].isPlayer )
  191.       {
  192.          // check if there is a path to this entity 130 units above his feet. if not, they're probably indoors
  193.          indoors = !maps\mp\gametypes\_weapons::weaponDamageTracePassed( ents[i].entity.origin, ents[i].entity.origin + (0,0,130), 0, undefined );
  194.          if ( !indoors )
  195.          {
  196.             indoors = !maps\mp\gametypes\_weapons::weaponDamageTracePassed( ents[i].entity.origin + (0,0,130), pos + (0,0,130 - 16), 0, undefined );
  197.             if ( indoors )
  198.             {
  199.                // give them a distance advantage for being indoors.
  200.                dist *= 4;
  201.                if ( dist > radius )
  202.                   continue;
  203.             }
  204.          }
  205.       }
  206.  
  207.       ents[i].damage = int(max + (min-max)*dist/radius);
  208.       ents[i].pos = pos;
  209.       ents[i].damageOwner = owner;
  210.       ents[i].eInflictor = eInflictor;
  211.       level.airStrikeDamagedEnts[level.airStrikeDamagedEntsCount] = ents[i];
  212.       level.airStrikeDamagedEntsCount++;
  213.    }
  214.  
  215.       thread BomberDamageEntsThread();
  216. }
  217.  
  218. BomberDamageEntsThread()
  219. {
  220.    self notify ( "BomberDamageEntsThread" );
  221.    self endon ( "BomberDamageEntsThread" );
  222.  
  223.    for ( ; level.airstrikeDamagedEntsIndex < level.airstrikeDamagedEntsCount; level.airstrikeDamagedEntsIndex++ )
  224.    {
  225.       if ( !isDefined( level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] ) )
  226.          continue;
  227.  
  228.       ent = level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex];
  229.      
  230.       if ( !isDefined( ent.entity ) )
  231.          continue;
  232.          
  233.       if ( !ent.isPlayer || isAlive( ent.entity ) )
  234.       {
  235.          ent maps\mp\gametypes\_weapons::damageEnt(
  236.             ent.eInflictor, // eInflictor = the entity that causes the damage (e.g. a claymore)
  237.             ent.damageOwner, // eAttacker = the player that is attacking
  238.             ent.damage, // iDamage = the amount of damage to do
  239.             "MOD_PROJECTILE_SPLASH", // sMeansOfDeath = string specifying the method of death (e.g. "MOD_PROJECTILE_SPLASH")
  240.             "stealth_mp", // sWeapon = string specifying the weapon used (e.g. "claymore_mp")
  241.             ent.pos, // damagepos = the position damage is coming from
  242.             vectornormalize(ent.damageCenter - ent.pos) // damagedir = the direction damage is moving in
  243.          );        
  244.  
  245.          level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] = undefined;
  246.          
  247.          if ( ent.isPlayer )
  248.             wait ( 0.05 );
  249.       }
  250.       else
  251.       {
  252.          level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] = undefined;
  253.       }
  254.    }
  255. }
  256.  
  257. radiusArtilleryShellshock(pos, radius, maxduration,minduration)
  258. {
  259.    players = level.players;
  260.    for (i = 0; i < players.size; i++)
  261.    {
  262.       if (!isalive(players[i]))
  263.          continue;
  264.      
  265.       playerpos = players[i].origin + (0,0,32);
  266.       dist = distance(pos, playerpos);
  267.       if (dist < radius) {
  268.          duration = int(maxduration + (minduration-maxduration)*dist/radius);
  269.          
  270.          players[i] thread artilleryShellshock("default", duration);
  271.       }
  272.    }
  273. }
  274.  
  275. artilleryShellshock(type, duration)
  276. {
  277.    if (isdefined(self.beingArtilleryShellshocked) && self.beingArtilleryShellshocked)
  278.       return;
  279.    self.beingArtilleryShellshocked = true;
  280.    
  281.    self shellshock(type, duration);
  282.    wait(duration + 1);
  283.    
  284.    self.beingArtilleryShellshocked = false;
  285. }
  286.  
  287. /#
  288. airstrikeLine( start, end, color, duration )
  289. {
  290.    frames = duration * 20;
  291.    for ( i = 0; i < frames; i++ )
  292.    {
  293.       line(start,end,color);
  294.       wait .05;
  295.    }
  296. }
  297.  
  298. traceBomb()
  299. {
  300.    self endon("death");
  301.    prevpos = self.origin;
  302.    while(1)
  303.    {
  304.       thread airstrikeLine( prevpos, self.origin, (.5,1,0), 20 );
  305.       prevpos = self.origin;
  306.       wait .2;
  307.    }
  308. }
  309. #/
  310.  
  311. doBombStrike( owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction , airStrikeType)
  312. {
  313.    // plane spawning randomness = up to 125 units, biased towards 0
  314.    // radius of bomb damage is 512
  315.  
  316.    if ( !isDefined( owner ) )
  317.       return;
  318.      
  319.    startPathRandomness = 150;
  320.    endPathRandomness = 150;
  321.      
  322.    pathStart = startPoint + ( (randomfloat(2) - 2)*startPathRandomness, (randomfloat(2) - 2)*startPathRandomness, 0 );
  323.    pathEnd   = endPoint   + ( (randomfloat(2) - 2)*endPathRandomness  , (randomfloat(2) - 2)*endPathRandomness  , 0 );
  324.    
  325.    //Assume no change in height on flightpath
  326.    height = (startpoint[2] - bombsite[2]);
  327.    midpoint = bombsite + (0,0,height);
  328.    totaldistance = distance2D(pathstart, pathend);
  329.    speed = totaldistance / flytime; //Units per second
  330.  
  331.    //Assume 45 degree drop angle to find range in xy from bombsite to releasepoint.
  332.    range = height / sin(45) * cos(45);
  333.    releasepoint = midpoint - anglestoforward(direction) * range;
  334.  
  335.    //Using plane velocity calculate time from start point to release point.
  336.    //New bombtime replaces original.
  337.    releaseDistance = distance2D(releasepoint, pathStart);
  338.    bombtime = releaseDistance / speed;
  339.    
  340.    // Spawn the planes
  341.    plane = spawnplane( owner, "script_model", pathStart );
  342.    plane setModel( "jokers_stealth" );
  343.    plane.angles = direction;
  344.    
  345.    plane spawnStealthFx();
  346.      
  347.    plane moveTo( pathEnd, flyTime, 0, 0 );
  348.      
  349.    thread stealthBomber_killCam( plane, pathEnd, flyTime, airStrikeType );
  350.    
  351.    thread callBomber_planeSound( plane, bombsite );
  352.    
  353.    for ( b = 0; b < 20; b++ ) {
  354.       thread callStrike_bombEffect( plane, bombTime - 0.1, owner, requiredDeathCount );
  355.       wait 0.09;
  356. }
  357.  
  358.    // Delete the plane after its flyby
  359.    wait flyTime;
  360.    plane notify( "delete" );
  361.    plane delete();
  362. }
  363.  
  364. callStrike_bombEffect( plane, launchTime, owner, requiredDeathCount )
  365. {
  366.    wait ( launchTime );
  367.  
  368.    plane thread play_sound_in_space( "veh_mig29_sonic_boom" );
  369.    bomb = spawnbomb( plane.origin, plane.angles );
  370.    bomb.ownerRequiredDeathCount = requiredDeathCount;
  371.  
  372.    //RUN TRACE TO FIND HIT POINT. ASSUME 45 DEGREE ANGLE
  373.    trace = bullettrace( bomb.origin, bomb.origin + anglestoForward( (45, bomb.angles[1], 0) ) * 5000, false, plane);
  374.    hit = trace["position"] + (0,0,50);
  375.    bomb moveto(hit, 2, 2);
  376.    bomb rotateTo( (45,bomb.angles[1], bomb.angles[2]), 2);
  377.  
  378.    /#
  379.    if ( getdvar("scr_airstrikedebug") == "1" )
  380.        bomb thread traceBomb();
  381.    #/
  382.  
  383.    wait ( 0.85 );
  384.    bomb.killCamEnt = spawn( "script_model", bomb.origin + (0,0,200) );
  385.    bomb.killCamEnt.angles = bomb.angles;
  386.    bomb.killCamEnt thread deleteAfterTime( 10.0 );
  387.    bomb.killCamEnt moveTo( bomb.killCamEnt.origin + vector_scale( anglestoforward( plane.angles ), 1000 ), 3.0 );
  388.    wait ( 0.15 );
  389.  
  390.  
  391.    wait 1; // 2 SECONDS MINUS THE KILLCAM WAIT TIMES.
  392.  
  393.    newBomb = spawn( "script_model", bomb.origin );
  394.    newBomb setModel( "tag_origin" );
  395.      newBomb.origin = bomb.origin;
  396.      newBomb.angles = bomb.angles;
  397.  
  398.    bomb setModel( "tag_origin" );
  399.    wait (0.05);
  400.  
  401.  
  402.    bombOrigin = newBomb.origin;
  403.    bombAngles = newBomb.angles;
  404.    playfxontag( level.bomberfx, newBomb, "tag_origin" );
  405.  
  406.    wait ( 0.05 );
  407.    repeat = 12; //BOMBLETS
  408.    minAngles = 55;
  409.    maxAngles = 100;
  410.    angleDiff = (maxAngles - minAngles) / repeat;
  411.  
  412.    for( i = 0; i < repeat; i++ )
  413.    {
  414.       traceDir = anglesToForward( bombAngles + (maxAngles-(angleDiff * i),randomInt( 10 )-5,0) );
  415.       traceEnd = bombOrigin + vector_scale( traceDir, 100 );
  416.       trace = bulletTrace( bombOrigin, traceEnd, false, undefined );
  417.  
  418.       traceHit = trace["position"];
  419.  
  420.       /#
  421.       if ( getdvar("scr_airstrikedebug") == "1" )
  422.          thread airstrikeLine( bombOrigin, traceHit, (1,0,0), 20 );
  423.       #/
  424.  
  425.       thread losRadiusDamage( traceHit + (0,0,16), 512, 200, 100, owner, bomb ); // targetpos, radius, maxdamage, mindamage, player causing damage, entity that player used to cause damage
  426.  
  427.       if ( i%3 == 0 )
  428.       {
  429.          thread playsoundinspace( "artillery_impact", traceHit );
  430.          playRumbleOnPosition( "artillery_rumble", traceHit );
  431.          earthquake( 0.7, 0.75, traceHit, 1000 );
  432.       }
  433.  
  434.       wait ( 0.05 );
  435.    }
  436.    wait ( 5.0 );
  437.    newBomb delete();
  438.    bomb delete();
  439. }
  440. spawnbomb( origin, angles )
  441. {
  442.    bomb = spawn( "script_model", origin );
  443.    bomb.angles = angles;
  444.    bomb setModel( "projectile_cbu97_clusterbomb" );
  445.  
  446.         bomb thread playPlaneFx(); //----------------------------)
  447.  
  448.    return bomb;
  449. }
  450.  
  451. deleteAfterTime( time )
  452. {
  453.    self endon ( "death" );
  454.    wait ( 10.0 );
  455.    
  456.    self delete();
  457. }
  458.  
  459. drawLine( start, end, timeSlice )
  460. {
  461.    drawTime = int(timeSlice * 20);
  462.    for( time = 0; time < drawTime; time++ )
  463.    {
  464.       line( start, end, (1,0,0),false, 1 );
  465.       wait ( 0.05 );
  466.    }
  467. }
  468.  
  469. playPlaneFx()
  470. {
  471.    self endon ( "death" );
  472.  
  473.         wait 0.1;
  474.  
  475.         playfxontag( level.fx_airstrike_contrail, self, "tag_fx" );
  476. }
  477.  
  478. stealthBomber_killCam( plane, pathEnd, flyTime, typeOfStrike )
  479. {
  480.    plane waittill ( "begin_airstrike" );
  481.  
  482.    planedir = anglesToForward( plane.angles );
  483.    
  484.    killCamEnt = spawn( "script_model", plane.origin + (0,0,100) - planedir * 200 );
  485.    plane.killCamEnt = killCamEnt;
  486.    plane.airstrikeType = typeOfStrike;
  487.    killCamEnt.startTime = gettime();
  488.    killCamEnt thread deleteAfterTime( 15.0 );
  489.  
  490.    killCamEnt linkTo( plane, "tag_origin", (-256,768,768), ( 0,0,0 ) );
  491. }
  492.  
  493. getBestBomberDirection( hitpos )
  494. {
  495.    if ( getdvarint("scr_airstrikebestangle") != 1 )
  496.       return randomfloat( 360 );
  497.    
  498.    checkPitch = -25;
  499.    
  500.    numChecks = 15;
  501.    
  502.    startpos = hitpos + (0,0,64);
  503.    
  504.    bestangle = randomfloat( 360 );
  505.    bestanglefrac = 0;
  506.    
  507.    fullTraceResults = [];
  508.    
  509.    for ( i = 0; i < numChecks; i++ )
  510.    {
  511.       yaw = ((i * 1.0 + randomfloat(1)) / numChecks) * 360.0;
  512.       angle = (checkPitch, yaw + 180, 0);
  513.       dir = anglesToForward( angle );
  514.      
  515.       endpos = startpos + dir * 1500;
  516.      
  517.       trace = bullettrace( startpos, endpos, false, undefined );
  518.      
  519.       if ( trace["fraction"] > bestanglefrac )
  520.       {
  521.          bestanglefrac = trace["fraction"];
  522.          bestangle = yaw;
  523.          
  524.          if ( trace["fraction"] >= 1 )
  525.             fullTraceResults[ fullTraceResults.size ] = yaw;
  526.       }
  527.      
  528.       if ( i % 3 == 0 )
  529.          wait .05;
  530.    }
  531.    
  532.    if ( fullTraceResults.size > 0 )
  533.       return fullTraceResults[ randomint( fullTraceResults.size ) ];
  534.    
  535.    return bestangle;
  536. }
  537.  
  538. callBomber( owner, coord, yaw )
  539. {  
  540.    // Get starting and ending point for the plane
  541.    direction = ( 0 , yaw , 0 );
  542.    planeHalfDistance = 10000;
  543.    planeBombExplodeDistance = 500;
  544.    planeFlyHeight = 500.0 + randomFloat(500.0);
  545.    planeFlySpeed = 1000.0 + randomFloat(1000.0);
  546.  
  547.    if ( isdefined( level.airstrikeHeightScale ) )
  548.    {
  549.       planeFlyHeight *= level.airstrikeHeightScale;
  550.    }
  551.    
  552.    startPoint = coord + vector_scale( anglestoforward( direction ), -1 * planeHalfDistance );
  553.    startPoint += ( 0, 0, planeFlyHeight );
  554.  
  555.    endPoint = coord + vector_scale( anglestoforward( direction ), planeHalfDistance );
  556.    endPoint += ( 0, 0, planeFlyHeight );
  557.    
  558.    // Make the plane fly by
  559.    d = length( startPoint - endPoint );
  560.    flyTime = ( d / planeFlySpeed );
  561.    
  562.    // bomb explodes planeBombExplodeDistance after the plane passes the center
  563.    d = abs( d/2 + planeBombExplodeDistance  );
  564.    bombTime = ( d / planeFlySpeed );
  565.    
  566.    owner endon("disconnect");
  567.    
  568.    requiredDeathCount = owner.deathCount;
  569.    
  570.    level.airstrikeDamagedEnts = [];
  571.    level.airStrikeDamagedEntsCount = 0;
  572.    level.airStrikeDamagedEntsIndex = 0;
  573.    level thread doBombStrike( owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(1000)), endPoint+(0,0,randomInt(1000)), bombTime, flyTime, direction );
  574. }
  575.  
  576. callEscort( owner, coord, yaw, bombtime, requiredDeathCount )
  577. {  
  578.    // Get starting and ending point for the plane
  579.    direction = ( 0 , yaw , 0 );
  580.    planeHalfDistance = 10000;
  581.    planeFlyHeight = 500.0 + randomFloat(500.0);
  582.    planeFlySpeed = 1000.0 + randomFloat(1000.0);
  583.  
  584.    if ( isdefined( level.airstrikeHeightScale ) )
  585.    {
  586.       planeFlyHeight *= level.airstrikeHeightScale;
  587.    }
  588.    
  589.    startPoint = coord + vector_scale( anglestoforward( direction ), -1 * planeHalfDistance );
  590.    startPoint += ( 0, 0, planeFlyHeight );
  591.  
  592.    endPoint = coord + vector_scale( anglestoforward( direction ), planeHalfDistance );
  593.    endPoint += ( 0, 0, planeFlyHeight );
  594.    
  595.    // Make the plane fly by
  596.    d = length( startPoint - endPoint );
  597.    flyTime = ( d / planeFlySpeed );
  598.    
  599.    owner endon("disconnect");
  600.  
  601.    level thread doFlyby( owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(1000)), endPoint+(0,0,randomInt(1000)), bombTime, flyTime, direction );
  602.    
  603. }
  604.  
  605. doFlyby( owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction , airStrikeType)
  606. {
  607.    // plane spawning randomness = up to 125 units, biased towards 0
  608.    if ( !isDefined( owner ) )
  609.       return;
  610.      
  611.    startPathRandomness = 150;
  612.    endPathRandomness = 150;
  613.      
  614.    pathStart = startPoint + ( (randomfloat(2) - 2)*startPathRandomness, (randomfloat(2) - 2)*startPathRandomness, 0 );
  615.    pathEnd   = endPoint   + ( (randomfloat(2) - 2)*endPathRandomness  , (randomfloat(2) - 2)*endPathRandomness  , 0 );
  616.    
  617.    //Assume no change in height on flightpath
  618.    height = (startpoint[2] - bombsite[2]);
  619.    totaldistance = distance2D(pathstart, pathend);
  620.    speed = totaldistance / flytime; //Units per second
  621.  
  622.    // Spawn the planes
  623.    plane = spawnplane( owner, "script_model", pathStart );
  624.    plane setModel( "jokers_stealth" ); //CHANGE THE MODEL TO THE MIG
  625.    plane.angles = direction;
  626.    
  627.    plane spawnStealthFx(); //IS THIS NEEDED?
  628.    plane moveTo( pathEnd, flyTime, 0, 0 );
  629.    
  630.    thread callBomber_planeSound( plane, bombsite ); //CHANGE TO MIG SOUND
  631.  
  632.    // Delete the plane after its flyby
  633.    wait flyTime;
  634.    plane notify( "delete" );
  635.    plane delete();
  636. }
  637.  
  638. callBomber_bomb( bombTime, coord, repeat, owner )
  639. {
  640.    accuracyRadius = 512;
  641.    
  642.    for( i = 0; i < repeat; i++ )
  643.    {
  644.       randVec = ( 0, randomint( 360 ), 0 );
  645.       bombPoint = coord + vector_scale( anglestoforward( randVec ), accuracyRadius );
  646.      
  647.       wait bombTime;
  648.      
  649.       thread playsoundinspace( "artillery_impact", bombPoint );
  650.       radiusArtilleryShellshock( bombPoint, 512, 8, 4);
  651.       losRadiusDamage( bombPoint + (0,0,16), 768, 300, 50, owner); // targetpos, radius, maxdamage, mindamage, player causing damage
  652.    }
  653. }
  654.  
  655. callBomber_planeSound( plane, bombsite )
  656. {
  657.    plane thread play_loop_sound_on_entity( "veh_mig29_dist_loop" );
  658.    while( !targetisclose( plane, bombsite ) )
  659.    wait 0.05;
  660.    plane notify ( "stop sound" + "veh_mig29_dist_loop" );
  661.    plane thread play_loop_sound_on_entity( "veh_mig29_close_loop" );
  662.    while( targetisinfront( plane, bombsite ) )
  663.    wait 0.05;
  664.    wait .5;
  665.    //plane thread play_sound_in_space( "veh_mig29_sonic_boom" );
  666.    while( targetisclose( plane, bombsite ) )
  667.    wait 0.05;
  668.    plane notify ( "stop sound" + "veh_mig29_close_loop" );
  669.    plane thread play_loop_sound_on_entity( "veh_mig29_dist_loop" );
  670.    plane waittill( "delete" );
  671.    plane notify ( "stop sound" + "veh_mig29_dist_loop" );
  672. }
  673.  
  674. playSoundinSpace (alias, origin, master)
  675. {
  676.    org = spawn ("script_origin",(0,0,1));
  677.    if (!isdefined (origin))
  678.       origin = self.origin;
  679.    org.origin = origin;
  680.    if (isdefined(master) && master)
  681.       org playsoundasmaster (alias);
  682.    else
  683.       org playsound (alias);
  684.    wait ( 10.0 );
  685.    org delete();
  686. }
  687.  
  688. play_loop_sound_on_entity(alias, offset)
  689. {
  690.    org = spawn ("script_origin",(0,0,0));
  691.    org endon ("death");
  692.    thread delete_on_death (org);
  693.    if (isdefined (offset))
  694.    {
  695.       org.origin = self.origin + offset;
  696.       org.angles = self.angles;
  697.       org linkto (self);
  698.    }
  699.    else
  700.    {
  701.       org.origin = self.origin;
  702.       org.angles = self.angles;
  703.       org linkto (self);
  704.    }
  705.  
  706.    org playloopsound (alias);
  707.    self waittill ("stop sound" + alias);
  708.    org stoploopsound (alias);
  709.    org delete();
  710. }
  711.  
  712. selectBomberLocation( hardpointType )
  713. {
  714.    self beginLocationSelection( "map_artillery_selector", level.artilleryDangerMaxRadius * 1.2 );
  715.    self.selectingLocation = true;
  716.  
  717.    self thread endSelectionOn( "cancel_location" );
  718.    self thread endSelectionOn( "death" );
  719.    self thread endSelectionOn( "disconnect" );
  720.    self thread endSelectionOn( "used" );
  721.    self thread endSelectionOnGameEnd();
  722.  
  723.    self endon( "stop_location_selection" );
  724.    self waittill( "confirm_location", location );
  725.  
  726.    if ( isDefined( level.bomberInProgress ) )
  727.    {
  728.       self iPrintLnBold( level.hardpointHints["bomber_mp_not_available"] );
  729.       self thread stopBomberLocationSelection( false );
  730.       return false;
  731.    }
  732.  
  733.    self.eow_hardpointtype = hardpointtype;
  734.    self thread finishBomberUsage( location, ::useBomber );
  735.    return true;
  736. }
  737.  
  738. finishBomberUsage( location, usedCallback )
  739. {
  740.    self notify( "used" );
  741.    wait ( 0.05 );
  742.    self thread stopBomberLocationSelection( false );
  743.    self thread [[usedCallback]]( location );
  744.    return true;
  745. }
  746.  
  747. endSelectionOn( waitfor )
  748. {
  749.    self endon( "stop_location_selection" );  
  750.    self waittill( waitfor );
  751.    self thread stopBomberLocationSelection( (waitfor == "disconnect") );
  752. }
  753.  
  754. endSelectionOnGameEnd()
  755. {
  756.    self endon( "stop_location_selection" );  
  757.    level waittill( "game_ended" );  
  758.    self thread stopBomberLocationSelection( false );
  759. }
  760.  
  761. stopBomberLocationSelection( disconnected )
  762. {
  763.    if ( !disconnected )
  764.    {
  765.       self endLocationSelection();
  766.       self.selectingLocation = undefined;
  767.    }
  768.    self notify( "stop_location_selection" );
  769. }
  770.  
  771. useBomber( pos )
  772. {
  773.    trace = bullettrace( self.origin + (0,0,10000), self.origin, false, undefined );
  774.    pos = (pos[0], pos[1], trace["position"][2] - 514);
  775.  
  776.    thread doBomb( pos, self, self.pers["team"] );
  777. }
  778.  
  779. flat_origin(org)
  780. {
  781.    rorg = (org[0],org[1],0);
  782.    return rorg;
  783. }
  784.  
  785. flat_angle(angle)
  786. {
  787.    rangle = (0,angle[1],0);
  788.    return rangle;
  789. }
  790.  
  791. targetisclose(other, target)
  792. {
  793.    infront = targetisinfront(other, target);
  794.    if(infront)
  795.       dir = 1;
  796.    else
  797.       dir = -1;
  798.    a = flat_origin(other.origin);
  799.    b = a+vector_scale(anglestoforward(flat_angle(other.angles)), (dir*100000));
  800.    point = pointOnSegmentNearestToPoint(a,b, target);
  801.    dist = distance(a,point);
  802.    if (dist < 3000)
  803.       return true;
  804.    else
  805.       return false;
  806. }
  807.  
  808. targetisinfront(other, target)
  809. {
  810.    forwardvec = anglestoforward(flat_angle(other.angles));
  811.    normalvec = vectorNormalize(flat_origin(target)-other.origin);
  812.    dot = vectordot(forwardvec,normalvec);
  813.    if(dot > 0)
  814.       return true;
  815.    else
  816.       return false;
  817. }
  818.  
  819. delete_on_death (ent)
  820. {
  821.    ent endon ("death");
  822.    self waittill ("death");
  823.    if (isdefined (ent))
  824.       ent delete();
  825. }
  826.  
  827.  
  828. spawnStealthFx()
  829. {
  830.    self endon ( "death" );
  831.    
  832.    wait .07;
  833.    playfxontag( level.fx_heli_green_blink, self, "tag_left_wingtip" );
  834.    playfxontag( level.fx_heli_green_blink, self, "tag_right_wingtip" );
  835. }
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