#include maps\mp\_utility;
#include common_scripts\utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\_audio;

//rocket fire settings
CONST_rocket_reload_time   = 6;
CONST_rocket_fire_interval = 0.05;
CONST_WARBIRD_RELOAD_MASH_TIME_RATIO = (50 / CONST_rocket_reload_time); // => 50 ms time decrease per button press / 6 sec max reload time

//warbird combat tuning
CONST_target_aquire_time	= 1;
CONST_los_recheck_time		= 0.25;
CONST_warbird_move_time_min = 4;
CONST_warbird_move_time_max = 8;

CONST_warbird_timeout		  = 30;
CONST_warbird_timeout_upgrade = 45;

//warbird cloak tuning
CONST_cloak_duration		  = 10;
CONST_cloak_cooldown_min_duration = 5;

CONST_second_warbird_height = 500;
	
init()
{
	level.warbirdSetting						  = [];
	level.warbirdSetting[ "Warbird" ]			  = SpawnStruct();
	level.warbirdSetting[ "Warbird" ].vehicle	  = "warbird_player_mp";
	level.warbirdSetting[ "Warbird" ].modelBase	  = "vehicle_xh9_warbird_low_cloaked_in_out_mp_cloak";
	level.warbirdSetting[ "Warbird" ].heliType	  = "warbird";
	level.warbirdSetting[ "Warbird" ].maxHealth	  = level.heli_maxhealth;

	level.killstreakFuncs[ "warbird" ] = ::tryUseWarbird;
	
	level.killstreakWieldWeapons["warbird_remote_turret_mp"] = "warbird";
	level.killstreakWieldWeapons["warbird_player_turret_mp"] = "warbird";
	level.killstreakWieldWeapons["warbird_missile_mp"] = "warbird";
	level.killstreakWieldWeapons["paint_missile_killstreak_mp"] = "warbird";
	
	if ( !IsDefined( level.SpawnedWarbirds ) )
		level.SpawnedWarbirds = [];
	
	if ( !IsDefined( level.warbirdInUse ) )
		level.warbirdInUse = false;
	
	level.chopper_fx["light"]["warbird"] = LoadFX( "vfx/lights/air_light_wingtip_red" );
	level.chopper_fx["engine"]["warbird"] = LoadFX( "vfx/distortion/distortion_warbird_mp" );
	
	maps\mp\killstreaks\_aerial_utility::makeHeliType( "warbird", "vfx/explosion/vehicle_warbird_explosion_midair", ::warbirdLightFX );
	maps\mp\killstreaks\_aerial_utility::addAirExplosion( "warbird", "vfx/explosion/vehicle_warbird_explosion_midair" );
	
/#
	SetDvarIfUninitialized( "scr_player_notarget", 0 );
	SetDvarIfUninitialized( "scr_warbird_timeout", 0 );
	SetDvarIfUninitialized( "scr_warbird_testcloak", 0 );
#/
	
	// Coop Buddy Assistance VO
	game["dialog"][ "assist_mp_warbird" ] = "ks_warbird_joinreq";
	game["dialog"][ "pilot_sup_mp_warbird" ] = "pilot_sup_mp_warbird";
	game["dialog"][ "pilot_aslt_mp_warbird" ] = "pilot_aslt_mp_warbird";
	game["dialog"][ "ks_warbird_destroyed" ] = "ks_warbird_destroyed";
	
//	initHeliAI();
}

tryUseWarbird( lifeId, modules )
{
	if ( !self CanUseWarbird() )
	{
		self IPrintLnBold( &"KILLSTREAKS_AIR_SPACE_TOO_CROWDED" );
		return false;
	}
	else if ( currentActiveVehicleCount() >= maxVehiclesAllowed() || level.fauxVehicleCount + 1 >= maxVehiclesAllowed() )
	{
		self IPrintLnBold( &"MP_TOO_MANY_VEHICLES" );
		return false;
	}

	// increment the faux vehicle count before we spawn the vehicle so no other vehicles try to spawn
	incrementFauxVehicleCount();
	level.warbirdInUse = true;
	
	hasAIOption = array_contains( modules, "warbird_ai_attack" ) || array_contains( modules, "warbird_ai_follow" );
	if ( !hasAIOption )
	{
		self thread playerClearWarbirdOnTeamChange();
		result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak( "warbird" );
		if ( result != "success" )
		{
			decrementFauxVehicleCount();
			level.warbirdInUse = false;
			return false;
		}
		self setUsingRemote( "warbird" );
	}

	result = self SetupWarbirdKillStreak( lifeId, modules );
	
	if( result )
	{
		self maps\mp\_matchdata::logKillstreakEvent( "warbird", self.origin );
	}

	return result;
}

playerClearWarbirdOnTeamChange()
{
	self endon( "rideKillstreakBlack" );
	self endon( "rideKillstreakFailed" );

	self waittill( "joined_team" );
	
	level.warbirdInUse = false;
	decrementFauxVehicleCount();
}

CanUseWarbird()
{
	return ( !level.warbirdInUse );
}

IsControllingWarbird()
{
	return ( IsDefined( self.ControllingWarbird ) && self.ControllingWarbird );
}

warbirdMakeVehicleSolidCapsule()
{
	self endon( "death" );
	//added frame for heli to spawn fully
	waitframe();
	
	//radius and offset should match vehHelicopterBoundsRadius (GDT) and bg_vehicle_sphere_bounds_offset_z.
	self MakeVehicleSolidCapsule( 300, -9, 160 );

}

setupPlayerCommands( modules )
{
	if ( IsBot( self ) )
		return;
	
	self NotifyOnPlayerCommand( "SwitchVisionMode"	 , "+actionslot 1" );
	self NotifyOnPlayerCommand( "SwitchWeapon"		 , "weapnext" );
	self NotifyOnPlayerCommand( "ToggleControlState" , "+activate" );
	self NotifyOnPlayerCommand( "ToggleControlCancel", "-activate" );
	self NotifyOnPlayerCommand( "ToggleControlState" , "+usereload" );
	self NotifyOnPlayerCommand( "ToggleControlCancel", "-usereload" );
	self NotifyOnPlayerCommand( "StartFire"			 , "+attack" );
	self NotifyOnPlayerCommand( "StartFire"			 , "+attack_akimbo_accessible" );
	if ( IsDefined( modules ) && array_contains( modules, "warbird_cloak" ) )
		self NotifyOnPlayerCommand( "Cloak"				, "+smoke" );
}

disablePlayercommands( warbird )
{
	if ( IsBot( self ) )
		return;
	
	self NotifyOnPlayerCommandRemove( "SwitchVisionMode"   , "+actionslot 1" );
	self NotifyOnPlayerCommandRemove( "SwitchWeapon"	   , "weapnext" );
	self NotifyOnPlayerCommandRemove( "ToggleControlState" , "+activate" );
	self NotifyOnPlayerCommandRemove( "ToggleControlCancel", "-activate" );
	self NotifyOnPlayerCommandRemove( "ToggleControlState" , "+usereload" );
	self NotifyOnPlayerCommandRemove( "ToggleControlCancel", "-usereload" );
	self NotifyOnPlayerCommandRemove( "StartFire"		   , "+attack" );
	self NotifyOnPlayerCommandRemove( "StartFire"		   , "+attack_akimbo_accessible" );
	if ( IsDefined( warbird ) && warbird.canCloak )
		self NotifyOnPlayerCommandRemove( "Cloak"				, "+smoke" );
}

SetupWarbirdKillStreak( lifeId, modules )
{	
	self endon( "warbirdStreakComplete" );
    
	self setupPlayerCommands( modules );
	
	self.PossessWarbird = false;
	self.ControllingWarbird = false;
	self.WarbirdInit = true;
	
	flightPathNodes = BuildValidFlightPaths();
	SpawnPoint = FindBestSpawnLocation( flightPathNodes );
	SpawnPoint = RotateHeliSpawn( SpawnPoint );
	
	warbird	= SpawnHelicopter( self, SpawnPoint.origin, SpawnPoint.angles, level.warbirdSetting[ "Warbird" ].vehicle, level.warbirdSetting[ "Warbird" ].modelBase );
	warbird.currentNode = SpawnPoint;

	if ( !IsDefined( warbird ) )	
		return false;
	
	warbird thread warbird_audio();
	warbird Hide();
	
	warbird thread warbirdMakeVehicleSolidCapsule();
	
	warbird.TargetEnt = Spawn( "script_origin", ( 0, 0, 0 ) );

	warbird.vehicleType			 = "Warbird";
	warbird.heli_type			 = level.warbirdSetting[ "Warbird" ].heliType;//level.warbirdSetting[ "Warbird" ].modelBase;
	warbird.heliType			 = level.warbirdSetting[ "Warbird" ].heliType;
	warbird.attractor			 = Missile_CreateAttractorEnt( warbird, level.heli_attract_strength, level.heli_attract_range );
	warbird.lifeId				 = lifeId;
	warbird.team				 = self.pers[ "team" ];
	warbird.pers[ "team" ]		 = self.pers[ "team" ];
	warbird.owner				 = self;
	warbird.maxhealth			 = level.warbirdSetting[ "Warbird" ].maxHealth;
	warbird.zOffset				 = ( 0, 0, 0 );
	warbird.targeting_delay		 = level.heli_targeting_delay;
	warbird.primaryTarget		 = undefined;
	warbird.secondaryTarget		 = undefined;
	warbird.attacker			 = undefined;
	warbird.currentstate		 = "ok";
	warbird.pickNewTarget		 = true;
	warbird.lineOfSight			 = false;
	warbird.overheattime		 = 6;
	warbird.firetime			 = 0;
	warbird.weaponfire			 = false;
	warbird.IsMoving			 = true;
	warbird.CloakCooldown		 = 0;
	warbird.isCrashing			 = false;
	warbird.IsPossessed			 = false;
	warbird.modules = modules;
	warbird.aiAttack = array_contains( warbird.modules, "warbird_ai_attack" );
	warbird.aiFollow = array_contains( warbird.modules, "warbird_ai_follow" );
	warbird.hasAI = ( warbird.aiAttack || warbird.aiFollow );
	warbird.canCloak = array_contains( warbird.modules, "warbird_cloak" );
	warbird.hasRockets = array_contains( warbird.modules, "warbird_rockets" );
	warbird.coopOffensive = array_contains( warbird.modules, "warbird_coop_offensive" );
	warbird.extraFlare = array_contains( warbird.modules, "warbird_flares" );
	
	if ( warbird.extraFlare )
		warbird.numExtraFlares = 1;
	else
		warbird.numExtraFlares = 0;
	
	if ( warbird.hasRockets )
		warbird.RocketClip = 3;
	else
		warbird.RocketClip = 0;
	warbird.RemainingRocketShots = warbird.RocketClip;
	
	//add global usable that the user can activate to possess the warbird
	if ( warbird.hasAI )
	{
		warbird.UsableEnt = Spawn( "script_origin", (0, 0, 0) );
		warbird.UsableEnt LinkTo( warbird );
		warbird.UsableEnt makeGloballyUsableByType( "killstreakRemote", &"MP_WARBIRD_PLAYER_PROMPT", self );
	}

	//------------------
	
	warbird thread [[ level.lightFxFunc[ "warbird" ] ]]();
	
	warbird make_entity_sentient_mp( warbird.team );

	if(!IsDefined(level.SpawnedWarbirds))
		level.SpawnedWarbirds = [];
	
	level.SpawnedWarbirds = array_add(level.SpawnedWarbirds,warbird);
	
	warbird maps\mp\killstreaks\_aerial_utility::addToHeliList();
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_flares_monitor( warbird.numExtraFlares );	
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave_on_disconnect( self );
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave_on_changeTeams( self );
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave_on_gameended( self );
	
	lifeSpan = CONST_warbird_timeout;
	if ( array_contains( warbird.modules, "warbird_time" ) )
		lifeSpan = CONST_warbird_timeout_upgrade;
	
	if ( self _hasPerk( "specialty_blackbox" ) && IsDefined( self.specialty_blackbox_bonus ) )
	{
		lifeSpan *= self.specialty_blackbox_bonus;
	}
	
/#
	if ( GetDvar( "scr_warbird_timeout", "0" ) != "0" )
		lifeSpan = GetDvarFloat( "scr_warbird_timeout" );
#/
	
	warbird.endTime = GetTime() + ( lifeSpan * 1000 );
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave_on_timeout( lifeSpan );
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_monitorEMP();
	warbird thread maps\mp\gametypes\_damage::setEntityDamageCallback( warbird.maxhealth, undefined, ::warbirdOnDeath, maps\mp\killstreaks\_aerial_utility::heli_ModifyDamage, true );
	warbird thread warbird_health();		
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_existance();
		
	self thread MonitorAIWarbirdDeathorTimeout( warbird );
	self thread MonitorPlayerDisconnect( warbird );
	
	warbird.warbirdTurret = warbird spawn_warbird_turret( "warbird_remote_turret_mp", "vehicle_xh9_warbird_turret_cloaked_inout_killstreak_mp_cloak", "tag_player_mp", false );
	warbird.warbirdTurret Hide();
	if ( !warbird.aiAttack && !warbird.aiFollow )
		warbird.warbirdTurret ShowToPlayer( self );

	buddyTurretWeaponInfo = "orbitalsupport_big_turret_mp";
	
	if ( warbird.coopOffensive )
		buddyTurretWeaponInfo = "warbird_remote_turret_mp";
	
	warbird.warbirdBuddyTurret = warbird spawn_warbird_turret( buddyTurretWeaponInfo, "vehicle_xh9_warbird_turret_cloaked_inout_killstreak_mp_cloak", "tag_playerbuddy_mp", true );
	warbird.warbirdBuddyTurret Hide();

	self thread SetupCloaking( warbird );
	thread WarbirdOverheatBarColorMonitor( warbird, warbird.warbirdTurret );
	
	if ( warbird.aiAttack || warbird.aiFollow )
	{
		self thread playerMonitorWarbirdPossession( warbird );
	}
	else
	{
		self thread PlayerControlWarbirdSetup( warbird );
	}
	
/#
	thread testFlares( self );
#/
	
	if(IsDefined(warbird))
	{
		if ( level.teamBased )
			level thread handleCoopJoining( warbird, self );
				
		return true;
	}
	else
		return false;
}

playerMonitorWarbirdPossession( warbird ) // self == player
{
	self endon( "warbirdStreakComplete" );
	
	warbird waittill( "cloaked" );
	waitframe();
	
	while (true)
	{
		self MonitorAIWarbirdSwitch( warbird );
		
		warbird.UsableEnt waittill( "trigger" );
		
		self thread manuallyJoinWarbird();
		self PlayerControlWarbirdSetup( warbird );
	}
}

manuallyJoinWarbird()
{
	self.manuallyJoiningKillStreak = true;
	
	self waittill_any( "death", "initRideKillstreak_complete", "warbirdStreakComplete" );
	
	self.manuallyJoiningKillStreak = false;
}

warbirdOnDeath( attacker, weapon, meansOfDeath, damage )
{
	self maps\mp\gametypes\_damage::onKillstreakKilled( attacker, weapon, meansOfDeath, damage, "warbird_destroyed", "ks_warbird_destroyed", "callout_destroyed_warbird", true );	
}

SetupCloaking( warbird )
{
	warbird.cloakState = 0;
	self CloakingTransition( warbird, true, true );	// turn cloaking on to force a state change when we make it visible
}

////=================================================================================================================//
////												WARBIRD HUD					                                     //
////=================================================================================================================//


WarbirdRocketHudUpdate( warbird )
{
	if ( !warbird.hasRockets )
		return;
    
	switch(warbird.RemainingRocketShots)
	{
		case 0:
			self SetClientOmnvar( "ui_warbird_missile", 0 );
			break;
		case 1:
			self SetClientOmnvar( "ui_warbird_missile", 1 );
			break;
		case 2:
			self SetClientOmnvar( "ui_warbird_missile", 2 );
			break;
		case 3:
			self SetClientOmnvar( "ui_warbird_missile", 3 );
			break;
	}
}

SetupWarbirdHud( warbird, isBuddy, primaryPlayer )		//self = player, primaryPlayer = the killstreak's primary owner, if coop
{
	self endon( "warbirdStreakComplete" );
	warbird endon( "death" );
	self endon( "ResumeWarbirdAI" );
	
	if ( !IsDefined( isBuddy ) )
		isBuddy = false;

	// Anyone spectating this player should be forced into first person
	self ForceFirstPersonWhenFollowed();
	
	self maps\mp\killstreaks\_aerial_utility::playerDisableStreakStatic();
	wait( 0.05 );
	if ( isBuddy )
		self SetClientOmnvar( "ui_warbird_toggle", 2 );
	else
		self SetClientOmnvar( "ui_warbird_toggle", 1 );
	self maps\mp\killstreaks\_aerial_utility::playerEnableStreakStatic();
	self SetClientOmnvar( "ui_warbird_cloak", false );
	self SetClientOmnvar( "ui_warbird_countdown", warbird.endTime );		//UI countdowns automatically subtract the current match time, so we have to add it back here with GetTime().
	if ( !isBuddy )
		self WarbirdRocketHudUpdate( warbird );
	
	if ( isBuddy && !warbird.coopOffensive )
		self SetClientOmnvar( "ui_warbird_weapon", 3 );
	else if ( isBuddy && warbird.coopOffensive )
		self SetClientOmnvar( "ui_warbird_weapon", 0 );
	else if ( warbird.hasRockets )
		self SetClientOmnvar( "ui_warbird_weapon", 1 );
	else
		self SetClientOmnvar( "ui_warbird_weapon", 0 );

	if( isBuddy )
	{
		coop_primary_num = primaryPlayer getEntityNumber();
		self SetClientOmnvar( "ui_coop_primary_num", coop_primary_num );
	}
	
	if ( warbird.canCloak && !isBuddy )
		self SetClientOmnvar( "ui_warbird_cloaktext", 1 );
	else
		self SetClientOmnvar( "ui_warbird_cloaktext", 0 );

	self SetClientOmnvar( "ui_killstreak_optic", false );
}

WarbirdOverheatBarColorMonitor( warbird, warbirdTurret )
{
	self endon( "warbirdStreakComplete" );
	warbird endon( "death" );
	
	while( true )
	{
		warbirdTurret.heat_level = warbirdTurret GetTurretHeat();
		self SetClientOmnvar( "ui_warbird_heat", warbirdTurret.heat_level );
		
		isOverheated = false;
		if ( IsDefined( warbirdTurret ) )
			isOverheated = warbirdTurret IsTurretOverheated();
		
		if ( isOverheated )
		{
			self SetClientOmnvar( "ui_warbird_fire", 1 );
		}
		else if ( warbirdTurret.heat_level > 0.7 )
		{
			self SetClientOmnvar( "ui_warbird_fire", 2 );
		}
		else
		{
			self SetClientOmnvar( "ui_warbird_fire", 0 );
		}
		
//		if ( isOverheated )
//			level thread handleOverheatWithMashHelp( self, warbirdTurret );
		
		while ( isOverheated )
		{
			wait 0.05;
			isOverheated = warbirdTurret IsTurretOverheated();
			warbirdTurret.heat_level = warbirdTurret GetTurretHeat();
			self SetClientOmnvar( "ui_warbird_heat", warbirdTurret.heat_level );
		}
		
		self notify( "overheatFinished" );
		
		waitframe();
	}
}

//handleOverheatWithMashHelp( player, warbirdTurret )
//{
//	warbirdTurret endon( "death" );
//	
//	heatDecreasePerButtonUp = ( 1 / 3 ) / 40;
//	
//	maxDecreaseHeat = 0.3;
//
////	numTimes = 0;
////	startTime = GetTime();
//	
//	while ( true )
//	{
//		result = player waittill_any_return_no_endon_death( "ToggleControlCancel", "overheatFinished" );
//		if ( IsDefined( result ) && result == "overheatFinished" )
//			break;
//		
//		isOverheated = warbirdTurret IsTurretOverheated();
//		if ( !isOverheated )
//			break;
//		
//		if ( maxDecreaseHeat - heatDecreasePerButtonUp >= 0 )
//		{
//			heat = warbirdTurret GetTurretHeat();
//			heat -= heatDecreasePerButtonUp;
//			maxDecreaseHeat -= heatDecreasePerButtonUp;
//			heat = clamp( heat, 0, 1 );
//			warbirdTurret SetTurretHeatWhenOverheating( heat );
////			numTimes++;		
//		}
//	}
//	
////	time = (GetTime() - startTime)/1000;
////	heatRemoved = (numTimes * heatDecreasePerButtonUp);
////	PrintLn( "Heat: NumUps: " + numTimes + ", HeatRemoved: " + heatRemoved + ", TimeReload: " + time );
//}


////=================================================================================================================//
////												TURRET SETUP				                                     //
////=================================================================================================================//

/*
=============
"Summary: returns a misc_turret that is attached self (a warbird)."
"<turretweaponinfo>: the turret type from turretsettings.gdt"
"<modelname>: the model to use for the turret"
"<linktotag>: the tag to which the turret will be attached"
=============
*/
spawn_warbird_turret( turretweaponinfo, modelname, linktotag, isBuddy )
{
	spawned_turret = SpawnTurret( "misc_turret", self GetTagOrigin( linktotag ), turretweaponinfo, false );
	spawned_turret.angles = self GetTagAngles( linktotag );
	spawned_turret SetModel( modelname );
	spawned_turret SetDefaultDropPitch( 45.0 );
	spawned_turret LinkTo( self, linktotag, ( 0,0,0 ), ( 0,0,0 ) );
	spawned_turret.owner = self.owner;
	spawned_turret.health = 99999;
	spawned_turret.maxHealth = 1000;
	spawned_turret.damageTaken = 0;
	spawned_turret.stunned = false;
	spawned_turret.stunnedTime = 0.0;
	spawned_turret SetCanDamage( false );
	spawned_turret SetCanRadiusDamage( false );
	spawned_turret.team = self.team;
	spawned_turret.pers["team"] = self.team;
	if ( level.teamBased )
	{
		spawned_turret SetTurretTeam( self.team );
	}
	spawned_turret SetMode( "sentry_manual" );
	spawned_turret SetSentryOwner( self.owner );
	spawned_turret SetTurretMinimapVisible( false );
	spawned_turret.chopper = self;
	
	if ( isBuddy )
	{
		spawned_turret.fireSoundent = Spawn( "script_model", self GetTagOrigin( linktotag ) );
		spawned_turret.fireSoundent SetModel( "tag_origin" );
		spawned_turret.fireSoundent LinkToSynchronizedParent( self, linktotag, ( 0, 0, 0 ), ( 0, 0, 0 ) );
	}
	
	return spawned_turret;
}

takeover_warbird_turret_buddy( warbird )
{
    if ( getDvarInt( "camera_thirdPerson" ) )
        self setThirdPersonDOF( false );

    warbird.warbirdBuddyTurret.owner = self;
	warbird.warbirdBuddyTurret SetMode( "sentry_manual" );
	warbird.warbirdBuddyTurret SetSentryOwner( self );

    self PlayerLinkWeaponViewToDelta( warbird.warbirdBuddyTurret, "tag_player", 0, 180, 180, -20, 180, false );
    self PlayerLinkedSetViewZNear( false );
    self PlayerLinkedSetUseBaseAngleForViewClamp( true );
    
	self RemoteControlTurret( warbird.warbirdBuddyTurret, 45, warbird.angles[1] );
}


////=================================================================================================================//
////											WARBIRD SPAWN LOGIC			                               		     //
////=================================================================================================================//

FindBestSpawnLocation(AttackPoints)
{
	SpawnPoints = get_array_of_closest( self.origin, AttackPoints );
	return SpawnPoints[ 0 ];
}
	
	
RotateHeliSpawn( SpawnPoint )
{
	MapCenter = maps\mp\killstreaks\_aerial_utility::getHeliAnchor();
	
	//Get the spawn forward direction as a vector
	SpawnPointForward = AnglesToForward( SpawnPoint.angles );
		
	//Get a vector from the spawn to the center
	VectorToCenter = MapCenter.origin - SpawnPoint.origin;
	
	//vector to angles
	NewOrientation = VectorToAngles( VectorToCenter );

	SpawnPoint.angles = NewOrientation;
	
	return SpawnPoint;	
}

BuildValidFlightPaths()
{
	self endon( "warbirdStreakComplete" );
	
	if ( !IsDefined( level.warbirdFlightPathNodes ) )
		level.warbirdFlightPathNodes = [];
	else
		return level.warbirdFlightPathNodes;
			
	firstNode = maps\mp\killstreaks\_aerial_utility::getEntOrStruct( "heli_loop_start", "targetname" );	
	prevNode = firstNode;
	warbirdHeight = maps\mp\killstreaks\_aerial_utility::getHeliAnchor();
	heightOriginZ = warbirdHeight.origin[2];
	
	while ( true )
	{
		nextNode = maps\mp\killstreaks\_aerial_utility::getEntOrStruct( prevNode.target, "targetname" );
		prevNode.next = nextNode;
		nextNode.prev = prevNode;
		nextNode.origin = ( nextNode.origin[0], nextNode.origin[1], heightOriginZ );
		if ( IsInArray( level.warbirdFlightPathNodes, nextNode ) )
			break;
		
		level.warbirdFlightPathNodes = array_add( level.warbirdFlightPathNodes, nextNode );	
		prevNode = nextNode;
	}
	
	foreach ( node in level.warbirdflightPathNodes )
	{
		Assert( IsDefined( node.next ) );
		assert( IsDefined( node.prev ) );
	}
	
	return level.warbirdFlightPathNodes;
}

IsInArray( array, Ent )
{
	if ( IsDefined( array ) )
	{
		foreach ( Index in array )
		{
			if ( Index == Ent )
				return true;
		}
	}
	return false;
}

////=================================================================================================================//
////										WARBIRD DEATH & BOUNDARY			                                     //
////=================================================================================================================//

MonitorWarbirdSafeArea( warbird )
{
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );
	
	self thread maps\mp\killstreaks\_aerial_utility::playerHandleBoundaryStatic( warbird, "warbirdStreakComplete", "ResumeWarbirdAI" );
	
	warbird waittill( "outOfBounds" );
			
	wait 2;
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave();
}


////=================================================================================================================//
////												AI Movement					                                     //
////=================================================================================================================//

WarbirdAIAttack( warbird )
{
	self thread WarbirdFire( warbird );
	self thread WarbirdLookAtEnemy( warbird );
	self thread WarbirdMoveToAttackPoint( warbird );
//	self thread debugEnemy( warbird );
}

//debugEnemy( warbird )
//{
//	self endon( "warbirdPlayerControlled" );
//	self endon( "warbirdStreakComplete" );
//	while ( true )
//	{
//		if ( IsDefined( warbird.enemy_target ) )
//			Line( warbird.origin, warbird.enemy_target.origin, ( 0, 1, 0 ), 1 );
//		
//		waitframe();
//	}
//}

WarbirdMoveToAttackPoint( warbird )
{		
	self endon( "warbirdPlayerControlled" );
	self endon( "warbirdStreakComplete" );

	baseSpeed = 40;
	warbird Vehicle_SetSpeed( baseSpeed, baseSpeed / 4, baseSpeed / 4 );
	warbird SetNearGoalNotifyDist( 100 );
	
	nextNode = warbird.currentNode;
	
	// get to the closest node
	if ( !IsDefined( nextNode ) )
	{
		SortedNodes = get_array_of_closest( warbird.origin, BuildValidFlightPaths() );
		
		start = warbird.origin;
		for ( i = 0; i < SortedNodes.size; i++ )
		{
			end = SortedNodes[i].origin;
			if ( maps\mp\killstreaks\_aerial_utility::flyNodeOrgTracePassed( start, end, warbird ) )
			{
				dir = end - start;
				dist = Distance( start, end );
				dirRight = RotateVector( dir, ( 0, 90, 0 ) );
				startWing = start + ( dirRight * 100 );
				endWing = startWing + ( dir * dist );
				if ( maps\mp\killstreaks\_aerial_utility::flyNodeOrgTracePassed( startWing, endWing, warbird ) )
				{
					dirLeft = RotateVector( dir , ( 0, -90, 0 ) );
					startWing = start + ( dirLeft * 100 );
					endWing = startWing + ( dir * dist );
					if ( maps\mp\killstreaks\_aerial_utility::flyNodeOrgTracePassed( startWing, endWing, warbird ) )
					{
						nextNode = SortedNodes[i];
						break;
					}
				}
			}
			waitframe();
		}
	}
	else
	{
		nextNode = nextNode.next;
	}
		
	if ( !IsDefined( nextNode ) )
		return;
	
	while ( true )
	{
		stopAtNode = false;
		if ( warbird.aiFollow )
			stopAtNode = true;
		warbird SetVehGoalPos( nextNode.origin, stopAtNode );
		
		warbird.IsMoving = true;
		
		warbird waittill( "near_goal" );
		
		warbird.currentNode = nextNode;
		warbird.IsMoving = false;
		
		nextNode = waitUntilMoveReturnNode( warbird );

		warbird.currentNode = undefined;
	}
}

waitUntilMoveReturnNode( warbird )
{
	if ( warbird.aiFollow && IsDefined( warbird.owner ) )
	{
		curNode = warbird.currentNode;
		prevNode = curNode.next;
		nextNode = curNode.prev;
		while ( IsDefined( warbird.owner ) )
		{
			
			curDistSq = Distance2DSquared( warbird.owner.origin, curNode.origin );
			prevDistSq = Distance2DSquared( warbird.owner.origin, prevNode.origin );
			nextDistSq = Distance2DSquared( warbird.owner.origin, nextNode.origin );
			
			if ( prevDistSq < curDistSq && prevDistSq < nextDistSq )
				return prevNode;
			else if ( nextDistSq < curDistSq && nextDistSq < prevDistSq )
				return nextNode;
			
			waitframe();
		}
	}
	else // aiattack
	{
//		wait( RandomFloatRange( CONST_warbird_move_time_min, CONST_warbird_move_time_max ) );
		return warbird.currentNode.next;
	}
}

WarbirdLookAtEnemy( warbird )
{
	self endon( "warbirdPlayerControlled" );
	self endon( "warbirdStreakComplete" );
	
	while ( 1 )
	{
		if ( IsDefined( warbird.enemy_target ) )
		{
			MonitorLookAtEnt( warbird );
			warbird.warbirdTurret ClearTargetEntity();
		}
		
		waitframe();
	}		
}

MonitorLookAtEnt( warbird )
{
	self endon( "warbirdPlayerControlled" );
	self endon( "warbirdStreakComplete" );
	warbird endon( "pickNewTarget" );
	
	warbird SetLookAtEnt( warbird.enemy_target );
	warbird.warbirdTurret SetTargetEntity( warbird.enemy_target );
	
	warbird.enemy_target waittill_either( "death", "disconnect" );
	warbird.pickNewTarget = true;
	warbird.lineOfSight	  = false;
}

////=================================================================================================================//
////												AI ATTACK					                                       //
////=================================================================================================================//

WarbirdFire( warbird )
{
	self endon( "warbirdPlayerControlled" );
	self endon( "warbirdStreakComplete" );

	thread FireAi( warbird );
			
	while ( true )
	{
		if ( warbird.pickNewTarget )
		{
			allGuys		 = level.participants;
			enemyTargets = [];
			
			foreach ( guy in allGuys )
			{
/#
				if ( !IsAI( guy ) && GetDvar( "scr_player_notarget", 0 ) != "0" )
					continue;
#/
				if ( guy.team != self.team )
					enemyTargets = array_add( enemyTargets, guy );
			}
			
			if ( warbird.aiAttack )
				enemyTargets = SortByDistance( enemyTargets, warbird.origin );
			else
				enemyTargets = SortByDistance( enemyTargets, self.origin );
			
			enemy_target = undefined;
			
			foreach ( guy in enemyTargets )
			{
				if ( !IsDefined( guy ) )
					continue;
				
				if ( !IsAlive( guy ) )
					continue;
				
				if ( guy _hasPerk( "specialty_blindeye" ) )
					continue;
				
				// 5 second ignore on spawn
				if ( isDefined( guy.spawntime ) && ( ( ( GetTime() - guy.spawntime ) / 1000 ) < 5 ) )
					continue;
				
				enemy_target		 = guy;
				warbird.enemy_target = enemy_target;
		
				CheckWarbirdTargetLos( warbird );	
				
				break;
			}
		}	
		
		warbird notify( "LostLOS" );
		
		wait( 0.05 );
	}
}

FireAi( warbird )
{
	self endon( "warbirdPlayerControlled" );
	self endon( "warbirdStreakComplete" );
	
	warbird.RemainingRocketShots = warbird.RocketClip;
	
	while ( true )
	{
		waitframe();
		
		if ( !IsDefined( warbird.enemy_target ) || !IsAlive( warbird.enemy_target ) || !warbird.lineOfSight )
			continue;
		
		if ( warbird.hasRockets && warbird.RemainingRocketShots )
		{
			FireAiRocket( warbird );
		}
		
		warbird.warbirdTurret ShootTurret();
	}
}

FireAiRocket( warbird )
{
	missile_tag_origin = warbird GetTagOrigin( "tag_missile_right" );
	player_forward	   = VectorNormalize( AnglesToForward( warbird.angles ) );
	warbird_velocity   = warbird Vehicle_GetVelocity();
	missile			   = MagicBullet( "warbird_missile_mp", missile_tag_origin + warbird_velocity / 10, self GetEye() + warbird_velocity + player_forward * 1000, self );
	missile.killCamEnt = warbird;
	PlayFXOnTag( level.chopper_fx[ "rocketlaunch" ][ "warbird" ], warbird, "tag_missile_right" );
	
	missile Missile_SetTargetEnt( warbird.enemy_target );
	missile Missile_SetFlightmodeDirect();
	
	warbird.RemainingRocketShots--;
	
	if ( warbird.RemainingRocketShots <= 0 )
		thread WarbirdAiRocketReload( warbird );
	
	waittillRocketDeath( warbird, missile );
}

WarbirdAiRocketReload( warbird )
{
	warbird endon( "warbirdStreakComplete" );
	
	wait CONST_rocket_reload_time;
	
	warbird.RemainingRocketShots = warbird.RocketClip;
}

waittillRocketDeath( warbird, missile )
{
	warbird.enemy_target endon( "death" );
	warbird.enemy_target endon( "disconnect" );
	
	missile waittill( "death" );
}

CheckWarbirdTargetLos( warbird )
{
	self endon( "warbirdPlayerControlled" );
	self endon( "warbirdStreakComplete" );
	warbird.enemy_target endon( "death" );
	warbird.enemy_target endon( "disconnect" );
	
	while ( true )
	{
		// occasionally check if you still have LOS to target
		turret_flash_pos = warbird GetTagOrigin( "TAG_FLASH1" );
		target_pos		 = warbird.enemy_target GetEye();
		target_dir		 = VectorNormalize( target_pos - turret_flash_pos );
		start_pos		 = turret_flash_pos + ( target_dir * 20 );
		
		trace = BulletTrace( start_pos, target_pos, false, warbird, false, false, false, false, false );
		if ( !CheckTargetIsInVision( warbird ) && trace["fraction"] < 1 )
		{
			warbird.lineOfSight	  = false;
			warbird.pickNewTarget = true;
			warbird.enemy_target = undefined;
			warbird notify( "pickNewTarget" );
			return;
		}
		
		warbird.lineOfSight = true;
		
		wait CONST_los_recheck_time;
	}
}

CheckTargetIsInVision( warbird )
{
	WarbirdForward			  = AnglesToForward( warbird.angles );
	WarbirdToEnemyLocation	  = warbird.enemy_target.origin - warbird.origin;
	DotProductToEnemyLocation = VectorDot( WarbirdForward, WarbirdToEnemyLocation );
	return DotProductToEnemyLocation < 0;
}

////=================================================================================================================//
////												PLAYER CONTROL				                                     //
////=================================================================================================================//

PlayerControlWarbirdSetup( warbird )
{
	self endon( "warbirdStreakComplete" );
	
	self.PossessWarbird = true;
	self.ControllingWarbird = true;
	
	warbird.player = self;
	warbird.currentNode = undefined;
	self playerSaveAngles();
	
	waitframe();
	
	self notify( "warbirdPlayerControlled" );
	warbird.IsPossessed	= true;
	
	warbird.killCamStartTime = undefined;
	warbird.warbirdTurret.killCamEnt = undefined;
	
	//set the using remote before setting weapon or initing the ride killstreak so that it is disabled properly for warbird death & timeouts
	if(self.WarbirdInit != true)
	{
		self _giveWeapon( "killstreak_predator_missile_mp" );
		self SwitchToWeapon( "killstreak_predator_missile_mp" );
	
		while ( self GetCurrentWeapon() != "killstreak_predator_missile_mp" )
			waitframe();
		
		self thread PlayerDoRideKillstreak( warbird, false );
		self waittill( "initRideKillstreak_complete", success );
		if ( !success )
			return;
		self setUsingRemote( "Warbird" );
	}
	
	self thread SetupWarbirdHud( warbird );
	self thread MonitorWarbirdSafeArea( warbird );
	
	// with the way we do visionsets we need to wait for the clearRideIntro() is done before we set thermal
	self thread waitSetThermal( 0.5 );
	self thread setWarbirdVisionSetPerMap( 0.5 );
	
	self EnableSlowAim(.3,.3);
	
	self pauseWarbirdEngineFXForPlayer( warbird );
	
	warbird.PlayerAttachPoint = Spawn( "script_model", ( 0, 0, 0 ) );
	warbird.PlayerAttachPoint SetModel( "tag_player" );
	warbird.PlayerAttachPoint Hide();
	
	WarbirdPlayerTagOrigin = ( warbird GetTagOrigin( "tag_origin" ) );
	WarbirdPlayerTagAngles = warbird GetTagAngles( "tag_origin" );
	forward				   = AnglesToForward( WarbirdPlayerTagAngles );
	
	WarbirdPlayerTagOrigin = WarbirdPlayerTagOrigin + ( forward * 165 );
	WarbirdPlayerTagOrigin += ( 0, 0, -10 );
	
	warbird.PlayerAttachPoint.origin = WarbirdPlayerTagOrigin;
	warbird.PlayerAttachPoint.angles = WarbirdPlayerTagAngles;
	
	warbird.PlayerAttachPoint LinkTo( warbird, "tag_player_mp" );
	
	//warbird VehicleTurretControlOn( self );

	self Unlink();

	warbird CancelAIMove( warbird );

	self thread WarbirdRocketDamageIndicator( warbird );
	//self thread WarbirdFreeRangeMode( warbird );
	self RemoteControlVehicle( warbird );
	
	self thread WeaponSetup( warbird );
	self thread PlayerCloakReady( warbird );
	warbird.warbirdTurret SetMode( "sentry_manual" );
	self RemoteControlTurret( warbird.warbirdTurret, 45 );
	
	while ( self.PossessWarbird )
		self ExitWarbirdControlState( warbird );
	
	self playerRestoreAngles();
	
	if ( !warbird.aiAttack && !warbird.aiFollow )
		warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave();
}

setWarbirdVisionSetPerMap( delay ) // self == player
{
	self endon( "disconnect" );
	self endon( "warbirdStreakComplete" );

	wait( delay );
	
	if ( IsDefined( level.warbirdVisionSet ) )
	{
		self SetClientTriggerVisionSet( level.warbirdVisionSet, 0 );
	}

//	self maps\mp\killstreaks\_aerial_utility::handle_player_starting_aerial_view();
}

removeWarbirdVisionSetPerMap( delay ) // self == player
{
	self SetClientTriggerVisionSet( "", delay );
//	self maps\mp\killstreaks\_aerial_utility::handle_player_ending_aerial_view();
}

PlayerDoRideKillstreak( warbird, isBuddy )
{
	if ( !IsDefined( isBuddy ) )
		isBuddy = false;
	
	type = "warbird";
	if ( isBuddy )
		type = "coop";
	result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak( type );
	
	if ( result != "success" || ( isBuddy && !level.warbirdInUse ) || !IsDefined( warbird ) || ( IsDefined( warbird.isleaving ) && warbird.isleaving ) )
	{
		if ( isBuddy )
			self removeWarbirdBuddy( warbird, result == "disconnect" );
		else if ( result != "disconnect" )
			self playerReset( warbird );
		
		self notify( "initRideKillstreak_complete", false );
		return;
	}
	
	self notify( "initRideKillstreak_complete", true );
}

ExitWarbirdControlState( warbird )
{
	self endon( "warbirdStreakComplete" );
	
	self waittill( "ToggleControlState" );
	
	self thread CancelExitButtonPressMonitor();
	self.PossessWarbird = false;
	
	wait 0.5;
	
	self notify( "ExitHoldTimeComplete" );
}

CancelExitButtonPressMonitor()
{
	self endon( "warbirdStreakComplete" );
	self endon( "ExitHoldTimeComplete" );
	
	self waittill( "ToggleControlCancel" );
	
	self.PossessWarbird = true;
}


waitSetThermal( delay )
{
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );

	wait( delay	);

	self ThermalVisionFOFOverlayOn();
	self SetBlurForPlayer( 1.1, 0 );
	
	adsAperature = 135;
	adsFocalDistance = 0;
	normalAperature = 60;
	normalFocalDistance = 0;
	focusSpeed = 12;
	aperatureSpeed = 5;
	self maps\mp\killstreaks\_aerial_utility::thermalVision( "warbirdThermalOff", adsAperature, adsFocalDistance, normalAperature, normalFocalDistance, focusSpeed, aperatureSpeed );
}

//=================================================================================================================//
//												PLAYER CLOAK				                                       //
//=================================================================================================================//

PlayerCloakReady( warbird, init )
{
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );
	
/#
	if ( GetDvar( "scr_warbird_testcloak", 0 ) != "0" )
		self thread playerTestCloak();
#/
	
	if(IsDefined(self.WarbirdInit) && self.WarbirdInit==true)
	{
		warbird waittill( "cloaked" );
		self waittill_any_return_no_endon_death( "ForceUncloak", "Cloak", "ResumeWarbirdAI" );
		
		self SwitchToVisible( warbird );
		warbird.PlayerAttachPoint play_sound_on_entity( "warbird_cloak_deactivate" );
		
		//warbird HideAllParts();
		
		//waitframe();
		
		//warbird ShowAllParts();

	}
	
	while( true )
	{
		thread PlayerCloakActivated( warbird );
		thread PlayerCloakCooldown( warbird );
		
		//wait the current cloak cooldown before switching to ready.
		if(warbird.CloakCooldown != 0)
		{
			self SetClientOmnvar( "ui_warbird_cloaktext", 3 );
			wait warbird.CloakCooldown;
		}

		self thread CloakReadyDialog();
		if ( warbird.canCloak )
			self SetClientOmnvar( "ui_warbird_cloaktext", 1 );
		
		self waittill( "Cloak" );
		
		self notify( "ActivateCloak" );
		
		warbird play_sound_on_entity( "warbird_cloak_activate" );

/#
		if ( GetDvar( "scr_warbird_testcloak", 0 ) != "0" )
			continue;
#/
		
		//the cloak has been used and has fully recharged.
		self waittill( "CloakCharged" );
	}
}

/#
playerTestCloak()
{
	self endon( "warbirdStreakComplete" );
	
	while ( true )
	{
		if ( level.player SecondaryOffhandButtonPressed() )
		{
			self notify( "Cloak" );
			wait 3;
		}
		
		waitframe();
	}
}
#/

PlayerCloakActivated( warbird )
{
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );
	
	self waittill( "ActivateCloak" );
	
	cloakMS = CONST_cloak_duration * 1000;
	self SetClientOmnvar( "ui_warbird_cloaktime", cloakMS + GetTime() );
	
	self SwitchToCloaked( warbird );
	self thread CloakActivatedDialog( warbird );
	
	self SetClientOmnvar( "ui_warbird_cloaktext", 2 );
	
	warbird.CloakCooldown = CONST_cloak_cooldown_min_duration;
	thread CloakCooldown( warbird );
	self thread PlayerCloakWaitForExit( warbird );
}

PlayerCloakCooldown( warbird )
{
	self endon( "warbirdStreakComplete" );
	self waittill( "UnCloak" );
	
	self thread PlayCloakOverheatDialog( warbird );	
	self SwitchToVisible( warbird );
	
	self SetClientOmnvar( "ui_warbird_cloaktext", 3 );
	
	self thread CloakDeactivatedDialog( warbird );
}

CloakCooldown( warbird )
{
	self endon( "warbirdStreakComplete" );
	self waittill( "UnCloak" );
	
	while(warbird.CloakCooldown>0)
	{
		warbird.CloakCooldown -= 0.5;
		wait 0.5;
	}
	
	warbird.CloakCooldown = 0;	
	self notify( "CloakCharged" );
}

PlayerCloakWaitForExit( warbird )
{
	self endon( "warbirdStreakComplete" );

	start = GetTime();
	self waittill_any_timeout_no_endon_death( CONST_cloak_duration, "ForceUncloak", "Cloak", "ResumeWarbirdAI" );
	end = GetTime();
	cooldownDuration = max( ( end - start ), CONST_cloak_cooldown_min_duration * 1000 );
	warbird.CloakCooldown = cooldownDuration / 1000;
	
	cooldownEnd = GetTime() + cooldownDuration;
	self SetClientOmnvar( "ui_warbird_cloakdur", cooldownEnd );

	self notify( "UnCloak" );
}
		
SwitchToCloaked( warbird )
{
	if(IsDefined(warbird))
	{
		thread CloakingTransition( warbird, true );
		Missile_DeleteAttractor( warbird.attractor );
		self SetClientOmnvar( "ui_warbird_cloak", true );
	
		thread MonitorDamageWhileCloaking( warbird );
	}
}

SwitchToVisible( warbird )
{
	if(IsDefined(warbird))
	{
		thread CloakingTransition( warbird, false );
		warbird.attractor = Missile_CreateAttractorEnt( warbird, level.heli_attract_strength, level.heli_attract_range );
		self SetClientOmnvar( "ui_warbird_cloak", false );
	}
}

CloakingTransition( warbird, enable, init )
{
	warbird notify( "cloaking_transition" );
	warbird endon( "cloaking_transition" );
	warbird endon( "warbirdStreakComplete" );
	
	if ( enable )
	{
		if ( warbird.cloakState == -2 )
			return;
		warbird.cloakState = -1;
		warbird CloakingEnable();
		warbird.warbirdTurret CloakingEnable();
		if ( warbird.coopOffensive )
			warbird.warbirdBuddyTurret CloakingEnable();
		warbird Vehicle_SetMinimapVisible( false );
		if ( !isdefined(init) || !init )
			wait 0.2;	// should match the code values for the transition + a small time
		else
			wait 1.5;	// during init, we want to give enough time for the cloaking to start then hide, before we unhide
		warbird Show();
		warbird.warbirdTurret Show();
		if ( warbird.coopOffensive )
			warbird.warbirdBuddyTurret Show();
		warbird.cloakState = -2;
		// don't hide the turret for the owner if possessed
		warbird notify( "cloaked" );
		warbird stopWarbirdEngineFX();
	}
	else
	{
		if ( warbird.cloakState == 2 )
			return;
		warbird.cloakState = 1;
		warbird CloakingDisable();
		warbird Vehicle_SetMinimapVisible( true );
		warbird.warbirdTurret CloakingDisable();
		if ( warbird.coopOffensive )
			warbird.warbirdBuddyTurret CloakingDisable();
		wait 2.2;	// should match the code values for the transition
		warbird.cloakState = 2;
		warbird playWarbirdEngineFX();
	}
}

CloakDeactivatedDialog( warbird )
{
	self endon( "CloakCharged" );
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );
	
	while ( true )
	{
		self waittill( "Cloak" );
		
		// iprintlnbold("OH NO YOU DON'T...");
		warbird.PlayerAttachPoint play_sound_on_entity( "warbird_cloak_notready" );
		
		wait 1;
	}
}

CloakReadyDialog()
{
	//warbird.PlayerAttachPoint thread play_sound_on_entity( "warbird_turret_overheat_warning" );	
}

CloakActivatedDialog( warbird )
{
	// warbird.PlayerAttachPoint thread play_sound_on_entity( "weap_warbirdrocket_reload" );
}

PlayCloakOverheatDialog( warbird )
{
	// warbird.PlayerAttachPoint thread play_sound_on_entity( "weap_warbirdrocket_reload" );
	warbird.PlayerAttachPoint play_sound_on_entity( "warbird_cloak_deactivate" );
}

CloakWarbirdExit( warbird, player )		//self = player
{
	if ( IsDefined( warbird ) && warbird.isCrashing == false )
	{
		if ( IsDefined( player ) )
			player notify( "ActivateCloak" );
		thread CloakingTransition( warbird, true );
		Missile_DeleteAttractor( warbird.attractor );
	}
}

MonitorDamageWhileCloaking( warbird )
{
	self endon( "UnCloak" );
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );
	
	//wait for the warbird to be fully cloaked
	wait 1;
	
	//if the warbird recieves any damage while fully cloaked it automatically ends the cloak behavior.
	warbird waittill( "damage", Amount, Attacker, DirectionVec, Point, DamageType );
	self notify( "ForceUncloak" );
}

//=================================================================================================================//
//											PLAYER DAMAGE MONITORS		                                   		   //
//=================================================================================================================//
WarbirdRocketDamageIndicator( warbird )
{
	self endon( "ResumeWarbirdAI" );
	self endon( "warbirdStreakComplete" );
	
	while(1)
	{
		warbird waittill( "damage", Amount, Attacker, DirectionVec, Point, DamageType );
		if( DamageType == "MOD_PROJECTILE" )
		{
			Earthquake ( .75, 1, warbird.origin, 1000 );	
			self ShellShock( "frag_grenade_mp", 0.5 );
		}
	}
}

////=================================================================================================================//
////												PLAYER ATTACK				                                       //
////=================================================================================================================//
UpdateShootingLocation( warbird )
{
	self endon( "warbirdStreakComplete" );
	level endon( "ResumeWarbirdAI" );
	
	while ( true )
	{
		angles = self GetPlayerAngles();
		
		eye = warbird.PlayerAttachPoint.origin;
		
		forward	  = AnglesToForward( angles );
		TargetPos = eye + ( forward * 4000 );
		
		warbird.TargetEnt.origin = TargetPos;
		
		//ForceTurretAimAtEnt( warbird, level.TargetEnt );
		
		wait 0.05;
	}
}

MonitorWeaponSelection( warbird )
{
	self endon( "warbirdStreakComplete" );
	self endon( "ResumeWarbirdAI" );
	
	self.current_warbird_weapon = "turret";
	warbird.warbirdTurret TurretFireEnable();
	
	if ( !warbird.hasRockets )
		return;
	
	while ( 1 )
	{
		self waittill( "SwitchWeapon" );
		
		if ( self.current_warbird_weapon == "turret" )
		{
			self.current_warbird_weapon = "missiles";
			warbird.warbirdTurret TurretFireDisable();
			self SetClientOmnvar( "ui_warbird_weapon", 2 );
		}
		else if ( self.current_warbird_weapon == "missiles" )
		{
			self.current_warbird_weapon = "turret";
			warbird.warbirdTurret TurretFireEnable();
			self SetClientOmnvar( "ui_warbird_weapon", 1 );
		}
		
		self PlayLocalSound( "warbird_weapon_cycle_plr" );
	}
}

WeaponSetup( warbird )
{
	if ( warbird.hasRockets )
		self thread FireWarbirdRockets( warbird );

	self thread MonitorWeaponSelection( warbird );

	self thread UpdateShootingLocation( warbird );
	//self thread MonitorWarbirdMachineGun( warbird );
	self thread force_uncloak_on_fire( warbird );
}

waittillTurretFired( warbird )
{
	warbird endon( "warbirdStreakComplete" );
	
	warbird.warbirdTurret endon( "turret_fire" );
	
	if ( warbird.coopOffensive )
		warbird.warbirdBuddyTurret endon( "turret_fire" );
	
	level waittill( "forever" );
}

force_uncloak_on_fire( warbird )		//self = player
{
	level endon( "game_ended" );
	self endon( "warbirdStreakComplete" );
	
	while ( true )
	{
		waittillTurretFired( warbird );
		self notify( "ForceUncloak" );
		
		wait( 0.05 );
	}
}

FireWarbirdThreatGrenades( warbird )
{
	warbird endon( "warbirdStreakComplete" );
	self endon( "warbirdStreakComplete" );
	self endon( "warbird_player_removed" );
	
	while ( true )
	{
		self waittill( "StartFire" );
		
		self maps\mp\killstreaks\_aerial_utility::playerFakeShootPaintMissile( warbird.warbirdBuddyTurret.fireSoundent );
		
		PlayFXOnTag(level.chopper_fx["rocketlaunch"]["warbird"], warbird, "tag_origin" );
		
		wait 2;
	}
}

FireWarbirdRockets( warbird )
{
	self endon( "ResumeWarbirdAI" );
	self endon( "warbirdStreakComplete" );

	warbird.RemainingRocketShots = warbird.RocketClip;
	
	while ( true )
	{
		if ( self.guid == "bot0" || self.guid == "bot1" || self.guid == "bot2" || self.guid == "bot3" )			//HACK: dirty, dirty hack to get the bots to continuously fire missiles. Strip this out before we ship!!!
		{
			wait( 3 );
		}
		else
		{
			self waittill( "StartFire" );
		}
		
		if ( self.current_warbird_weapon == "missiles" || ( self.guid == "bot0" || self.guid == "bot1" || self.guid == "bot2" || self.guid == "bot3" ) )			//HACK: dirty, dirty hack to get the bots to continuously fire missiles. Strip this out before we ship!!!
		{
			Earthquake ( 0.4, 1, warbird.origin, 1000 );
			self PlayRumbleOnEntity( "ac130_105mm_fire" );
			missile_tag_origin = warbird GetTagOrigin( "tag_missile_right" );
			player_forward = VectorNormalize( AnglesToForward( self GetPlayerAngles() ) );
			warbird_velocity = warbird GetEntityVelocity();
			missile = MagicBullet( "warbird_missile_mp", missile_tag_origin + warbird_velocity/10, self GetEye() + warbird_velocity + player_forward * 1000, self );
			PlayFXOnTag(level.chopper_fx["rocketlaunch"]["warbird"], warbird, "tag_missile_right");
			
			missile Missile_SetTargetEnt( warbird.TargetEnt );
			missile Missile_SetFlightmodeDirect();
			
			warbird.RemainingRocketShots--;
			
			self notify( "ForceUncloak" );
			
			WarbirdRocketHudUpdate( warbird );
			
			if ( warbird.RemainingRocketShots == 0 )
			{
				thread WarbirdRocketReloadSound( warbird, CONST_rocket_reload_time );
//				waittillReloadedWithMashHelp( CONST_rocket_reload_time, self, "rockets" );
				wait CONST_rocket_reload_time;
				warbird.RemainingRocketShots = warbird.RocketClip;
				self notify( "rocketReloadComplete" );
				WarbirdRocketHudUpdate( warbird );
			}
			else
			{
				wait CONST_rocket_fire_interval;
			}
		}
	}
}

WarbirdRocketReloadSound( warbird, reload_time )
{
	self endon( "rocketReloadComplete" );
	self endon( "ResumeWarbirdAI" );
	self endon( "warbirdStreakComplete" );

	missile_count = 3;
	
	self PlayLocalSound( "warbird_missile_reload_bed" );
	
	wait(0.5);

	while ( true )
	{
		self PlayLocalSound( "warbird_missile_reload" );
		wait( reload_time / missile_count );
	}	
}

////=================================================================================================================//
////												BUDDY - UI					                                     //
////=================================================================================================================//

handleCoopJoining( warbird, player )
{
	splashRef = "warbird_coop_defensive";
	joinText = &"MP_JOIN_WARBIRD_DEF";
	buddyJoinedVO = "pilot_sup_mp_warbird";
	joinedVO = "copilot_sup_mp_paladin";
	if ( warbird.coopOffensive )
	{
		splashRef = "warbird_coop_offensive";
		joinText = &"MP_JOIN_WARBIRD_OFF";
		buddyJoinedVO = "pilot_aslt_mp_warbird";
		joinedVO = "copilot_aslt_mp_paladin";
	}
	
	while ( true )
	{
		id = maps\mp\killstreaks\_coop_util::promptForStreakSupport( player.team, joinText, splashRef, "assist_mp_warbird", buddyJoinedVO, player, joinedVO );
		
		level thread watchForJoin( id, warbird, player );
		
		result = waittillPromptComplete( warbird, "buddyJoinedStreak" );
		
		maps\mp\killstreaks\_coop_util::stopPromptForStreakSupport( id );
		
		if ( !IsDefined( result ) )
			return;
		
		result = waittillPromptComplete( warbird, "buddyLeftWarbird" );
		
		if ( !IsDefined( result ) )
			return;
	}
}

waittillPromptComplete( warbird, text )
{
	warbird endon( "warbirdStreakComplete" );
	
	warbird waittill( text );
	
	return true;
}

watchForJoin( id, warbird, player )
{
	warbird endon( "warbirdStreakComplete" );
	
	buddy = maps\mp\killstreaks\_coop_util::waittillBuddyJoinedStreak( id );
	
	warbird notify( "buddyJoinedStreak" );
	buddy thread buddyJoinWarbirdSetup( warbird, player );
}

////=================================================================================================================//
////												BUDDY						                                     //
////=================================================================================================================//

buddyJoinWarbirdSetup( warbird, primaryPlayer )
{
	warbird endon( "warbirdStreakComplete" );
	self endon( "warbirdStreakComplete" );
	self endon( "warbird_player_removed" );

	self thread WarbirdOverheatBarColorMonitor( warbird, warbird.warbirdBuddyTurret );
	
	warbird.buddy = self;
	
	self.ControllingWarbird = true;
	
	self thread PlayerDoRideKillstreak( warbird, true );
	self waittill( "initRideKillstreak_complete", success );
	if ( !success )
		return;
	
	self setUsingRemote( "Warbird" );
	self playerSaveAngles();
	
	self thread SetupWarbirdHud( warbird, true, primaryPlayer );
	self thread MonitorBuddyWarbirdDeathorTimeout( warbird );
	self thread MonitorBuddyDisconnect( warbird );
	
	// with the way we do visionsets we need to wait for the clearRideIntro() is done before we set thermal
	self thread waitSetThermal( 0.5 );
	self thread setWarbirdVisionSetPerMap( 0.5 );
	
	self pauseWarbirdEngineFXForPlayer( warbird );
	
	self thread WarbirdRocketDamageIndicator( warbird );
	
	self takeover_warbird_turret_buddy( warbird );
	
	self setupPlayerCommands();
	
	if ( !warbird.coopOffensive )
		self thread FireWarbirdThreatGrenades( warbird );

	if ( !IsBot( self ) )
		self thread removeWarbirdBuddyOnCommand( warbird );
}

removeWarbirdBuddy( warbird, disconnected )
{
	self notify ( "warbird_player_removed" );
	
	if ( !disconnected )
	{
		self playerResetWarbirdOmnvars();
		self SetBlurForPlayer( 0, 0 );
		self notify( "warbirdThermalOff" );
		maps\mp\killstreaks\_aerial_utility::disableOrbitalThermal( self );
		self thread removeWarbirdVisionSetPerMap( 1.5 );
		self ThermalVisionFOFOverlayOff();
		if ( IsDefined( warbird.warbirdBuddyTurret ) && self IsControllingWarbird() )
			self RemoteControlTurretOff( warbird.warbirdBuddyTurret );
		self.ControllingWarbird = undefined;
		self EnableWeapons();
		self Unlink();
		self maps\mp\killstreaks\_coop_util::playerResetAfterCoopStreak();
		self DisableSlowAim();
		self disablePlayercommands( warbird );
		self restartWarbirdEngineFXForPlayer( warbird );
		if ( self isUsingRemote() )
			self clearUsingRemote();
		self playerRemoteKillstreakShowHud();
		self playerRestoreAngles();
	}
	
	warbird notify( "buddyLeftWarbird" );
	warbird.buddy = undefined;
}

MonitorBuddyWarbirdDeathorTimeout( warbird )
{
	self endon( "disconnect" );
	
	warbird waittill_any( "leaving", "death", "crashing" );
	
	self notify( "warbirdStreakComplete" );
	self notify ( "StopWaitForDisconnect" );
	
	waittillframeend;
	maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();

	self thread removeWarbirdBuddy( warbird, false );
}

MonitorBuddyDisconnect( warbird )
{
	self endon( "StopWaitForDisconnect" );
	
	self waittill( "disconnect" );
	
	thread removeWarbirdBuddy( warbird, true );
}

removeWarbirdBuddyOnCommand(warbird)
{
	self endon( "warbird_player_removed" );
	
	while ( true )
	{
		self waittill( "ToggleControlState" );
		
		self thread startWarbirdBuddyExitCommand(warbird);
		self thread cancelWarbirdBuddyExitCommand();
	}
}

startWarbirdBuddyExitCommand(warbird)
{
	self endon( "warbird_player_removed" );
	self endon( "ToggleControlCancel" );
	
	self.warbird_buddy_exit = true;
	
	wait( 0.5 );
	
	if ( self.warbird_buddy_exit == true )
	{
		self thread removeWarbirdBuddy( warbird, false );
	}
}

cancelWarbirdBuddyExitCommand()
{
	self endon( "warbird_player_removed" );
	
	self waittill( "ToggleControlCancel" );
	
	self.warbird_buddy_exit = false;
}

////=================================================================================================================//
////												RESUME AI FUNC				                                     //
////=================================================================================================================//

MonitorAIWarbirdSwitch( warbird, init )
{
	self endon( "warbirdStreakComplete" );
		
	self.WarbirdInit = false;
	
	self notify( "ResumeWarbirdAI" );
	self notify( "warbirdThermalOff" );
	warbird.IsPossessed	= false;
	self thread CloakingTransition( warbird, false );	// ensure the player sees the warbird

	warbird.warbirdTurret SetMode( "auto_nonai" );
	self playerResetWarbirdOmnvars();

	waittillframeend;
	
//	startNode = level.heli_start_nodes[ randomInt( level.heli_start_nodes.size ) ];
//	warbird thread heli_think( -1, warbird.owner, startNode, warbird.owner.team, "warbird" );
	self thread WarbirdAIAttack( warbird );
	
	warbird.killCamStartTime = GetTime();
	warbird.warbirdTurret.killCamEnt = warbird;
	
	warbird.player = undefined;

	if ( self isUsingRemote() )
		self playerReset( warbird );
	
	waitframe();
}


////=================================================================================================================//
////											DEATH TIMEOUT & DISCONNECT	                    	                 //
////=================================================================================================================//

MonitorAIWarbirdDeathorTimeout( warbird )
{
	self endon( "disconnect" );
	
	thread CheckForCrashing( warbird );
	
	result = warbird waittill_any_return( "leaving", "death", "crashing" );
	
	self playerResetAfterWarbird( warbird );
	level thread warbirdCleanup( warbird, self, (result != "death") );
}

warbirdCleanup( warbird, player, waitUntilDeath )
{
	level.SpawnedWarbirds = array_remove(level.SpawnedWarbirds,warbird);
	level.warbirdInUse = false;
	
	if ( IsDefined( warbird.UsableEnt ) )
		warbird.UsableEnt makeGloballyUnusableByType();
	
	thread CloakWarbirdExit( warbird, player );
	
	if ( IsDefined( warbird.attractor ) )
		Missile_DeleteAttractor( warbird.attractor );
		
	if ( IsDefined( warbird.PlayerAttachPoint ) )
		warbird.PlayerAttachPoint Delete();
	
	warbird.enemy_target = undefined;

	if ( waitUntilDeath )
		warbird waittill( "death" );
	else
		waittillframeend;
	
	result = maps\mp\gametypes\_hostmigration::waitTillHostMigrationDone();
	if ( result != 0 )
		waitframe();
	
	warbird.warbirdTurret Delete();

	if ( IsDefined( warbird.warbirdBuddyTurret ) )
	{
	    if ( IsDefined( warbird.warbirdBuddyTurret.fireSoundent ) )
	    	warbird.warbirdBuddyTurret.fireSoundent Delete();
		warbird.warbirdBuddyTurret Delete();
	}
	
	if ( IsDefined( warbird.UsableEnt ) )
		warbird.UsableEnt Delete();
}

playerResetAfterWarbird( warbird ) // self == player
{
	self notify( "warbirdStreakComplete" );
	warbird notify( "warbirdStreakComplete" );
	
	waittillframeend;

	self playerResetWarbirdOmnvars();

	///// check to see if player is actually in the warbird, because if they are in another vehicle then this will change that UI
	if ( warbird.IsPossessed && !self isInRemoteTransition() )
	{
		self playerReset( warbird );
		warbird.IsPossessed = false;
	}
	
	self disablePlayerCommands( warbird );
	
	self notify ( "StopWaitForDisconnect" );
}

playerReset( warbird ) // self == player
{
	self SetBlurForPlayer( 0, 0 );
	maps\mp\killstreaks\_aerial_utility::disableOrbitalThermal( self );		
	self ThermalVisionFOFOverlayOff();
	self thread removeWarbirdVisionSetPerMap( 1.5 );
	//warbird VehicleTurretControlOff( self );
	self RemoteControlVehicleOff();
	if ( IsDefined( warbird.warbirdTurret ) && self IsControllingWarbird() )
		self RemoteControlTurretOff( warbird.warbirdTurret );
	self.ControllingWarbird = undefined;
	self.PossessWarbird = undefined;
	self EnableWeapons();
	self Unlink();
	if ( self isUsingRemote() )
	{
		self clearUsingRemote();
	}
	else
	{
		curWeapon = self getCurrentWeapon();
		if( curWeapon == "none" || isKillstreakWeapon( curWeapon ) )
			self switchToWeapon( self Getlastweapon() );
		
		self playerRemoteKillstreakShowHud();
	}
	self thread playerDelayControl();
	if ( warbird.hasAI )
		self maps\mp\killstreaks\_killstreaks::takeKillstreakWeaponIfNoDupe( "killstreak_predator_missile_mp" );
	self EnableWeaponSwitch();
	self DisableSlowAim();
	if ( !IsDefined( warbird.isleaving ) || !warbird.isleaving )
		self restartWarbirdEngineFXForPlayer( warbird );
	self playerRestoreAngles();
}

playerDelayControl() // self == player
{
	self endon( "disconnect" );
	
	self freezeControlsWrapper( true );
	wait( 0.5 );
	self freezeControlsWrapper( false );
}

CheckForCrashing( warbird )
{
	warbird waittill_any( "crashing", "death" );
	warbird.isCrashing = true;
}
	
//I think this will take care of the player leaving mid match.  The warbird should just fly away and all the spawned entities should get deleted.
MonitorPlayerDisconnect( warbird )
{
	self endon ( "StopWaitForDisconnect" );
	
	self waittill( "disconnect" );
	
	warbird notify( "warbirdStreakComplete" );
	self notify( "warbirdStreakComplete" );
	self notify( "warbirdThermalOff" );
	
	warbird thread maps\mp\killstreaks\_aerial_utility::heli_leave();
	
	level thread warbirdCleanup( warbird, self, true );
}

play_sound_on_entity( alias )
{
	self PlaySound( alias );
}


warbird_health()
{
	self endon( "death" );
	self endon( "leaving" );
	self endon( "crashing" );
	
	self.currentstate = "ok";
	self.laststate = "ok";
	self setdamagestage( 3 );
	
	damageState = 3;
	self setDamageStage( damageState );
	
	for ( ;; )
	{
		if ( self.damageTaken >= (self.maxhealth * 0.33) && damageState == 3 )
		{
			damageState = 2;
			self setDamageStage( damageState );
			self.currentstate = "light smoke";
			playFxOnTag( level.chopper_fx["damage"]["light_smoke"], self, "tag_static_main_rotor_l" );
		}
		else if ( self.damageTaken >= (self.maxhealth * 0.66) && damageState == 2 )
		{
			damageState = 1;
			self setDamageStage( damageState );
			self.currentstate = "heavy smoke";
			stopFxOnTag( level.chopper_fx["damage"]["light_smoke"], self, "tag_static_main_rotor_l" );
			playFxOnTag( level.chopper_fx["damage"]["heavy_smoke"], self, "tag_static_main_rotor_l" );
		}
		else if( self.damageTaken >= self.maxhealth )
		{
			damageState = 0;
			self setDamageStage( damageState );

			//stopFxOnTag( level.chopper_fx["damage"]["light_smoke"], self, "tag_static_main_rotor_l" );
			//stopFxOnTag( level.chopper_fx["damage"]["heavy_smoke"], self, "tag_static_main_rotor_l" );
			
			if ( IsDefined( self.largeProjectileDamage ) && self.largeProjectileDamage )
			{
				self thread maps\mp\killstreaks\_aerial_utility::heli_explode( true );
			}
			else
			{
				playFxOnTag( level.chopper_fx["damage"]["on_fire"], self, "TAG_TAIL_FX" );
				self thread maps\mp\killstreaks\_aerial_utility::heli_crash();
			}
		}
		
		wait 0.05;
	}
}

playerResetWarbirdOmnvars()
{
	self SetClientOmnvar( "ui_warbird_heat", 0 );
	self SetClientOmnvar( "ui_warbird_flares", 0 );
	self SetClientOmnvar( "ui_warbird_fire", 0 );
	self SetClientOmnvar( "ui_warbird_cloak", false );
	self SetClientOmnvar( "ui_warbird_cloaktime", 0 );
	self SetClientOmnvar( "ui_warbird_cloakdur", 0 );
	self SetClientOmnvar( "ui_warbird_countdown", 0 );
	self SetClientOmnvar( "ui_warbird_missile", -1 );	
	self SetClientOmnvar( "ui_warbird_weapon", 0 );
	self SetClientOmnvar( "ui_warbird_cloaktext", 0 );
	self SetClientOmnvar( "ui_warbird_toggle", 0 );
	self SetClientOmnvar( "ui_coop_primary_num", 0 );
	self maps\mp\killstreaks\_aerial_utility::playerDisableStreakStatic();
	
	self DisableForceFirstPersonWhenFollowed();
}

//waittillReloadedWithMashHelp( reloadTime, player, type )
//{
//	self endon( "playerReloadTimeout" + type );
//	
//	player thread playerReloadTimeout( reloadTime, type );
//	
//	timeDecreasePerButtonUp = reloadTime * CONST_WARBIRD_RELOAD_MASH_TIME_RATIO;
//	reloadTimeMS = reloadTime * 1000;
//	reloadTimeComplete = GetTime() + reloadTimeMS;
//	
//	maxDecreaseTime = reloadTimeMS * 0.2;
//
////	numTimes = 0;
////	startTime = GetTime();
//	
//	while ( GetTime() < reloadTimeComplete )
//	{
//		if ( maxDecreaseTime - timeDecreasePerButtonUp >= 0 )
//		{
//			player waittill( "ToggleControlCancel" );
//			reloadTimeComplete -= timeDecreasePerButtonUp;
////			numTimes++;
//		}
//	}
//	
//	player notify( "playerReloadTimeoutMashed" + type );
//	
////	time = (GetTime() - startTime)/1000;
////	timeRemoved = (numTimes * timeDecreasePerButtonUp)/1000;
////	PrintLn( "NumUps: " + numTimes + ", TimeRemoved: " + timeRemoved + ", TimeReload: " + time );
//}
//
//playerReloadTimeout( reloadTime, type )
//{
//	self endon( "disconnect" );
//	self endon( "playerReloadTimeoutMashed" + type );
//	
//	wait reloadTime;
//	
//	self notify( "playerReloadTimeout" + type );
//}


////=========================================================================================//
////											VFX	                    	                 //
////=========================================================================================//

/*
=============
"Name: playWarbirdEngineFX()"
"Summary: plays warbird engine effects on a warbird"
=============
*/
playWarbirdEngineFX()
{
	PlayFXOnTag( level.chopper_fx["engine"]["warbird"], self, "tag_static_main_rotor_r" );
	PlayFXOnTag( level.chopper_fx["engine"]["warbird"], self, "tag_static_main_rotor_l" );
	
	if ( IsDefined( self.player ) )
		self.player pauseWarbirdEngineFXForPlayer( self );
	
	if ( IsDefined( self.buddy ) )
		self.buddy pauseWarbirdEngineFXForPlayer( self );
}

stopWarbirdEngineFX()
{
	StopFXOnTag( level.chopper_fx["engine"]["warbird"], self, "tag_static_main_rotor_r" );
	StopFXOnTag( level.chopper_fx["engine"]["warbird"], self, "tag_static_main_rotor_l" );
}

pauseWarbirdEngineFXForPlayer( warbird )
{
	if ( !IsDefined( warbird ) )
		return;
	
	StopFXOnTagForClient( level.chopper_fx["engine"]["warbird"], warbird, "tag_static_main_rotor_r", self );
	StopFXOnTagForClient( level.chopper_fx["engine"]["warbird"], warbird, "tag_static_main_rotor_l", self );
}

restartWarbirdEngineFXForPlayer( warbird )
{
	if ( !IsDefined( warbird ) )
		return;
	
	if ( maps\mp\killstreaks\_aerial_utility::vehicleIsCloaked() )
		return;

	PlayFXOnTagForClients( level.chopper_fx["engine"]["warbird"], warbird, "tag_static_main_rotor_r", self );
	PlayFXOnTagForClients( level.chopper_fx["engine"]["warbird"], warbird, "tag_static_main_rotor_l", self );
}

////=========================================================================================//
////											AUDIO	                    	                 //
////=========================================================================================//

warbird_audio()
{
	if(isdefined( self ))
	{
		//self snd_veh_play_loops( "warbird_close_lp", "warbird_close_stress_lp", "warbird_chopper_dist_lp" );
	}
}

warbirdLightFX()
{
	self endon( "death" );
	
	while ( true )
	{
		self.owner waittill( "UnCloak" );
		
		playFXOnTag( level.chopper_fx["light"]["warbird"], self, "tag_light_body_L" );
		wait ( 0.05 );
		playFXOnTag( level.chopper_fx["light"]["warbird"], self, "tag_light_body_R" );
		wait ( 0.05 );
		playFXOnTag( level.chopper_fx["light"]["warbird"], self, "tag_light_tail" );
		
		self.owner waittill( "ActivateCloak" );
		
		stopFXOnTag( level.chopper_fx["light"]["warbird"], self, "tag_light_body_L" );
		wait ( 0.05 );
		stopFXOnTag( level.chopper_fx["light"]["warbird"], self, "tag_light_body_R" );
		wait ( 0.05 );
		stopFXOnTag( level.chopper_fx["light"]["warbird"], self, "tag_light_tail" );
	}
}

/#
testFlares( player )
{
	player endon( "warbirdStreakComplete" );
	
	SetDvarIfUninitialized( "scr_warbird_flares", "0" );
	
	cur = "none";
	while ( true )
	{
		if ( GetDvarInt( "scr_warbird_flares", 0 ) == 0 )
		{
			waitframe();
			continue;
		}
		
		SetDvar( "scr_warbird_flares", "0" );
		
		if ( cur == "none" )
		{
			player SetClientOmnvar( "ui_warbird_flares", 3 );
			cur = "threat";
		}
		else if ( cur == "threat" )
		{
			player SetClientOmnvar( "ui_warbird_flares", 1 );
			cur = "flare1";
		}
		else if ( cur == "flare1" )
		{
			player SetClientOmnvar( "ui_warbird_flares", 2 );
			cur = "flare2";
		}
		else  // if ( cur == "flare2" )
		{
			player SetClientOmnvar( "ui_warbird_flares", 0 );
			cur = "none";
		}
		
		
		waitframe();
	}
}
#/