#include maps\mp\_utility; #include common_scripts\utility; init() { precacheVehicle( "attack_littlebird_mp" ); //precacheString( &"HELICOPTER_FLOCK_INBOUND" ); precacheModel( "vehicle_apache_mp" ); precacheModel( "vehicle_apache_mg" ); precacheTurret( "apache_minigun_mp" ); precacheVehicle( "apache_strafe_mp" ); level.killStreakFuncs["littlebird_flock"] = ::tryUseLbFlock; level.heli_flock = []; } tryUseLbFlock( lifeId, streakName ) { numIncomingVehicles = 5; if( heliFlockActive() || currentActiveVehicleCount() >= maxVehiclesAllowed() || level.fauxVehicleCount + numIncomingVehicles >= maxVehiclesAllowed() ) { self iPrintLnBold( &"KILLSTREAKS_TOO_MANY_VEHICLES" ); return false; } // increment the faux vehicle count before we spawn the vehicle so no other vehicles try to spawn incrementFauxVehicleCount(); incrementFauxVehicleCount(); incrementFauxVehicleCount(); incrementFauxVehicleCount(); incrementFauxVehicleCount(); result = self selectLbStrikeLocation( lifeId, "littlebird_flock" ); if ( ( !isDefined( result ) || !result ) ) { // decrement the faux vehicle count since this failed to spawn decrementFauxVehicleCount(); decrementFauxVehicleCount(); decrementFauxVehicleCount(); decrementFauxVehicleCount(); decrementFauxVehicleCount(); return false; } level thread teamPlayerCardSplash( "used_littlebird_flock", self, self.team ); return true; } heliFlockActive() { result = false; for ( i=0; i= maxVehiclesAllowed() || level.fauxVehicleCount >= maxVehiclesAllowed() ) { self iPrintLnBold( &"KILLSTREAKS_TOO_MANY_VEHICLES" ); self notify( "cancel_location" ); return false; } level.heli_flock = []; level.heli_flock_victims = []; self thread littlebirdMadeSelectionVO(); self thread finishLbStrikeUsage( lifeId, location, ::callStrike, locationYaw ); self setblurforplayer( 0, 0.3 ); return true; } littlebirdMadeSelectionVO() { self endon( "death" ); self endon( "disconnect" ); self PlayLocalSound( game[ "voice" ][ self.team ] + "KS_hqr_littlebird" ); wait( 3.0 ); self PlayLocalSound( game[ "voice" ][ self.team ] + "KS_lbd_inbound" ); } finishLbStrikeUsage( lifeId, location, usedCallback, locationYaw ) { self notify( "used" ); wait ( 0.05 ); self thread stopLocationSelection( false ); if ( isDefined( self ) ) self thread [[usedCallback]]( lifeId, location, locationYaw ); } callStrike( lifeId, location, locationYaw ) { level endon( "game_ended" ); self endon("disconnect"); self thread handleOwnerLeft(); // get flight paths all at once flightPath1 = getFlightPath( location, locationYaw, 0 ); flightPath2 = getFlightPath( location, locationYaw, -520 ); flightPath3 = getFlightPath( location, locationYaw, 520 ); flightPath4 = getFlightPath( location, locationYaw, -1040 ); flightPath5 = getFlightPath( location, locationYaw, 1040 ); // leader level thread doLbStrike( lifeId, self, flightPath1, 0 ); wait( 0.3 ); // left wingman level thread doLbStrike( lifeId, self, flightPath2, 1 ); // right wingman level thread doLbStrike( lifeId, self, flightPath3, 2 ); wait( 0.3 ); // left wingman level thread doLbStrike( lifeId, self, flightPath4, 3 ); // right wingman level thread doLbStrike( lifeId, self, flightPath5, 4 ); // log it self maps\mp\_matchdata::logKillstreakEvent( "littlebird_flock", location ); } getFlightPath( location, locationYaw, rightOffset ) { location = location * (1,1,0); initialDirection = ( 0, locationYaw, 0 ); planeHalfDistance = 12000; flightPath = []; if ( isDefined( rightOffset ) && rightOffset != 0 ) location = location + ( AnglesToRight( initialDirection ) * rightOffset ) + ( 0, 0, RandomInt( 300 ) ); // start point startPoint = ( location + ( AnglesToForward( initialDirection ) * ( -1 * planeHalfDistance ) ) ); // end point endPoint = ( location + ( AnglesToForward( initialDirection ) * planeHalfDistance ) ); // get height flyHeight = self maps\mp\killstreaks\_airdrop::getFlyHeightOffset( location ) + 256; flightPath["start"] = startPoint + ( 0, 0, flyHeight ); flightPath["end"] = endPoint + ( 0, 0, flyHeight ); return flightPath; } doLbStrike( lifeId, owner, flightPath, flockIndex ) { level endon( "game_ended" ); if ( !isDefined( owner ) ) return; forward = vectorToAngles( flightPath["end"] - flightPath["start"] ); lb = spawnAttackLittleBird( owner, flightPath["start"], forward, flockIndex ); lb.lifeId = lifeId; lb.alreadyDead = false; lb thread watchTimeOut(); lb thread watchDeath(); lb thread flock_handleDamage(); lb thread startLbFiring1(); lb thread monitorKills(); lb endon( "death" ); // initial target run lb SetMaxPitchRoll( 120, 60 ); lb Vehicle_SetSpeed( 48, 48 ); lb setVehGoalPos( flightPath["end"], 0 ); lb waittill( "goal" ); // turn lb SetMaxPitchRoll( 30, 40 ); lb Vehicle_SetSpeed( 32, 32 ); lb setVehGoalPos( flightPath["start"], 0 ); wait( 2 ); // return lb SetMaxPitchRoll( 100, 60 ); lb Vehicle_SetSpeed( 64, 64 ); lb waittill ( "goal" ); lb notify( "gone" ); // remove lb maps\mp\killstreaks\_helicopter::removeLittlebird(); } spawnAttackLittleBird( owner, origin, forward, flockIndex ) { lb = spawnHelicopter( owner, origin, forward, "apache_strafe_mp" , "vehicle_apache_mp" ); if ( !isDefined( lb ) ) return; lb maps\mp\killstreaks\_helicopter::addToLittleBirdList(); lb thread maps\mp\killstreaks\_helicopter::removeFromLittleBirdListOnDeath(); lb.health = 999999; // keep it from dying anywhere in code lb.maxHealth = 2000; // this is the health we'll check lb.damageTaken = 0; // how much damage has it taken lb setCanDamage( true ); lb.owner = owner; lb.team = owner.team; lb.killCount = 0; lb.streakName = "littlebird_flock"; lb.heliType = "littlebird"; //lb ThermalDrawEnable(); lb.specialDamageCallback = ::Callback_VehicleDamage; mgTurret1 = spawnTurret( "misc_turret", lb.origin, "apache_minigun_mp" ); mgTurret1 linkTo( lb, "tag_turret", (0,0,0), (0,0,0) ); mgTurret1 setModel( "vehicle_apache_mg" ); mgTurret1.angles = lb.angles; mgTurret1.owner = lb.owner; mgTurret1.team = mgTurret1.owner.team; mgTurret1 makeTurretInoperable(); mgTurret1.vehicle = lb; //mgTurret1 ThermalDrawEnable(); killCamOrigin = ( lb.origin + ( ( AnglesToForward( lb.angles ) * -200 ) + ( AnglesToRight( lb.angles ) * -200 ) ) ) + ( 0, 0, 50 ); mgTurret1.killCamEnt = Spawn( "script_model", killCamOrigin ); mgTurret1.killCamEnt SetScriptMoverKillCam( "explosive" ); mgTurret1.killCamEnt LinkTo( lb, "tag_origin" ); lb.mgTurret1 = mgTurret1; lb.mgTurret1 SetDefaultDropPitch( 0 ); lb.mgTurret1 setMode( "auto_nonai" ); lb.mgTurret1 SetSentryOwner( lb.owner ); if ( level.teamBased ) { lb.mgTurret1 setTurretTeam( lb.owner.team ); } level.heli_flock[flockIndex] = lb; return lb; } watchTimeOut() { level endon( "game_ended" ); self endon( "gone" ); self endon( "death" ); maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( 60.0 ); self notify( "death" ); } monitorKills() { level endon( "game_ended" ); self endon( "gone" ); self endon( "death" ); self endon( "stopFiring" ); for(;;) { self waittill( "killedPlayer", player ); self.killCount++; level.heli_flock_victims[level.heli_flock_victims.size] = player; } } startLbFiring1( ) { self endon( "gone" ); self endon( "death" ); self endon( "stopFiring" ); for( ;; ) { self.mgTurret1 waittill( "turret_on_target" ); fireOnTarget = true; targetPlayer = self.mgTurret1 GetTurretTarget( false ); foreach ( victim in level.heli_flock_victims ) { if ( targetPlayer == victim ) { self.mgTurret1 ClearTargetEntity(); fireOnTarget = false; break; } } if ( fireOnTarget ) self.mgTurret1 ShootTurret(); } } handleOwnerLeft() // self == owner { level endon( "game_ended" ); self endon( "flock_done" ); self thread notifyOnFlockDone(); self waittill( "killstreak_disowned" ); for ( i=0; i= self.maxHealth ) { if ( isPlayer( attacker ) && ( !isDefined( self.owner ) || attacker != self.owner ) ) { self.alreadyDead = true; attacker notify( "destroyed_helicopter" ); attacker notify( "destroyed_killstreak", weapon ); thread teamPlayerCardSplash( "callout_destroyed_helicopter", attacker ); attacker thread maps\mp\gametypes\_rank::giveRankXP( "kill", 300, weapon, meansOfDeath ); attacker thread maps\mp\gametypes\_rank::xpEventPopup( "destroyed_helicopter" ); thread maps\mp\gametypes\_missions::vehicleKilled( self.owner, self, undefined, attacker, damage, meansOfDeath, weapon ); } self notify ( "death" ); } } watchDeath() { self endon( "gone" ); self waittill( "death" ); self thread maps\mp\killstreaks\_helicopter::lbOnKilled(); }