#using scripts\codescripts\struct;

#using scripts\shared\challenges_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\hud_shared;
#using scripts\shared\math_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\util_shared;

#using scripts\mp\_util;
#using scripts\mp\gametypes\_battlechatter;
#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\gametypes\_spawning;
#using scripts\mp\killstreaks\_killstreakrules;
#using scripts\mp\killstreaks\_killstreaks;
#using scripts\shared\visionset_mgr_shared;

  
                                                                                                   	  	                                                                    	                     	                 	                                                                         	                       	                                                      	                                                      	                                                       	                                                                                                  	                                                                                                                 	                                                   	                	                                          	                                      	       	  	             	                                                     	                                                                             	                         	                                                                	                                                             	                                                             	                                                                                      	                                                         	                                                         	                                                               	                                                               	                                                   	                                                                	                                                     	                                                	                                                	                                                        	                                                                                                  	                                                                             	                                            	                                                                                    	                                          	                     	                                              	                                        	                 	   
#using scripts\mp\killstreaks\_killstreak_bundles;
#using scripts\mp\killstreaks\_killstreak_detect;
#using scripts\mp\killstreaks\_killstreak_hacking;
    	   	                                                                                                                                         	                                	                                                                                                                                                                                                                                                                                                                                                                    	        	     	              	    	   	               	                                              	                                                           	                               	                     	                                                                                                           	                                                                 	                                                              	                                                                                                                                             	                            	                                     	                                       	                                                                                                              	   	                  	       	                                                    	                   	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	                                                                                                 	                                    	                                                                                        	           	                        	                                            	                                             	                                                   	                                                             	                                                         	                                                                    	                                                                                                                                                                                                                                	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  	    	         	                                                              	                                                          	                                   	                                   	                                                    	                                       	                                           	     	                                                                                                                                                                                                                                                      	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	                                                               	        	                                                                                                                              	                                                                                                                     	                               	                                                      	                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	   	                                                                                                                                                                                                                                  	                                                                                                                                                                                                                                                                                                                                                                                                                                                   
                                             









	
//#precache( "material","tow_filter_overlay_no_signal");
#precache( "material", "hud_remote_missile_target" );
#precache( "string", "KILLSTREAK_EARNED_REMOTE_MISSILE" );
#precache( "string", "KILLSTREAK_REMOTE_MISSILE_NOT_AVAILABLE" );
#precache( "string", "KILLSTREAK_REMOTE_MISSILE_INBOUND" );
#precache( "string", "KILLSTREAK_REMOTE_MISSILE_HACKED" );
#precache( "eventstring", "mpl_killstreak_cruisemissile" );
#precache( "fx", "killstreaks/fx_predator_trigger" );

#namespace remotemissile;



function init()
{
	level.rockets = [];
	
	killstreaks::register( "remote_missile", "remote_missile", "killstreak_remote_missile", "remote_missle_used",&tryUsePredatorMissile, true );
	killstreaks::register_alt_weapon( "remote_missile", "remote_missile_missile" );
	killstreaks::register_alt_weapon( "remote_missile", "remote_missile_bomblet" );
	killstreaks::register_strings( "remote_missile", &"KILLSTREAK_EARNED_REMOTE_MISSILE", &"KILLSTREAK_REMOTE_MISSILE_NOT_AVAILABLE", &"KILLSTREAK_REMOTE_MISSILE_INBOUND", undefined, &"KILLSTREAK_REMOTE_MISSILE_HACKED" );
	killstreaks::register_dialog( "remote_missile", "mpl_killstreak_cruisemissile", "remoteMissileDialogBundle", "remoteMissilePilotDialogBundle", "friendlyRemoteMissile", "enemyRemoteMissile", "enemyRemoteMissileMultiple", "friendlyRemoteMissileHacked", "enemyRemoteMissileHacked", "requestRemoteMissile" );
	killstreaks::set_team_kill_penalty_scale( "remote_missile", level.teamKillReducedPenalty );
	killstreaks::override_entity_camera_in_demo("remote_missile", true);

	clientfield::register( "missile", "remote_missile_bomblet_fired", 1, 1, "int" );
	clientfield::register( "missile", "remote_missile_fired", 1, 2, "int" );
	
	level.missilesForSightTraces = [];

	level.missileRemoteDeployFX = "killstreaks/fx_predator_trigger";
	level.missileRemoteLaunchVert = 18000;
	level.missileRemoteLaunchHorz = 7000;
	level.missileRemoteLaunchTargetDist = 1500;
	
	visionset_mgr::register_info( "visionset", "remote_missile_visionset", 1, 110, 16, true, &visionset_mgr::ramp_in_out_thread_per_player, false  );
}

function remote_missile_game_end_think( rocket, team, killstreak_id )
{
	self endon( "Remotemissle_killstreak_done" );
	
	level waittill( "game_ended" );
	
	self thread player_missile_end( rocket, true, true, team, killstreak_id );

	self notify( "Remotemissle_killstreak_done" );
}

function tryUsePredatorMissile( lifeId )
{
	waterDepth = self depthofplayerinwater();
	
	if( !self IsOnGround() || self util::isUsingRemote() || ( waterDepth > 2 ) || self killstreaks::is_killstreak_start_blocked() )
	{
		self iPrintLnBold( &"KILLSTREAK_REMOTE_MISSILE_NOT_USABLE" );
		return false;
	}

	team = self.team;
	killstreak_id = self killstreakrules::killstreakStart( "remote_missile", team, false, true );
	if ( killstreak_id == -1 )
	{
		return false;
	}
	
	self.remoteMissilePilotIndex = killstreaks::get_random_pilot_index( "remote_missile" );
	
	returnVar = _fire( lifeId, self, team, killstreak_id );
	
	return returnVar;
}


function getBestSpawnPoint( remoteMissileSpawnPoints )
{
	validEnemies = [];

	foreach ( spawnPoint in remoteMissileSpawnPoints )
	{
		spawnPoint.validPlayers = [];
		spawnPoint.spawnScore = 0;
	}
	
	foreach ( player in level.players )
	{
		if ( !isAlive( player ) )
			continue;

		if ( player.team == self.team )
			continue;
		
		if ( player.team == "spectator" )
			continue;
		
		bestDistance = 999999999;
		bestSpawnPoint = undefined;
	
		foreach ( spawnPoint in remoteMissileSpawnPoints )
		{
			//could add a filtering component here but i dont know what it would be.
			spawnPoint.validPlayers[spawnPoint.validPlayers.size] = player;
		
			potentialBestDistance = Distance2DSquared( spawnPoint.targetent.origin, player.origin );
			
			if ( potentialBestDistance <= bestDistance )
			{
				bestDistance = potentialBestDistance;
				bestSpawnpoint = spawnPoint;	
			}	
		}

		bestSpawnPoint.spawnScore += 2;
	}

	bestSpawn = remoteMissileSpawnPoints[0];
	foreach ( spawnPoint in remoteMissileSpawnPoints )
	{
		foreach ( player in spawnPoint.validPlayers )
		{
			spawnPoint.spawnScore += 1;
			
			if ( bulletTracePassed( player.origin + (0,0,32), spawnPoint.origin, false, player ) )
				spawnPoint.spawnScore += 3;
		
			if ( spawnPoint.spawnScore > bestSpawn.spawnScore )
			{
				bestSpawn = spawnPoint;
			}
			else if ( spawnPoint.spawnScore == bestSpawn.spawnScore ) // equal spawn weights so we toss a coin.
			{			
				if ( math::cointoss() )
					bestSpawn = spawnPoint;	
			}
		}
	}
	
	return ( bestSpawn );
}

function drawLine( start, end, timeSlice, color )
{
	/#
	drawTime = int(timeSlice * 20);
	for( time = 0; time < drawTime; time++ )
	{
		line( start, end, color,false, 1 );
		{wait(.05);};
	}
	#/
}

function _fire( lifeId, player, team, killstreak_id )
{
	remoteMissileSpawnArray = getEntArray( "remoteMissileSpawn" , "targetname" );
	
	foreach ( spawn in remoteMissileSpawnArray )
	{
		if ( isdefined( spawn.target ) )
			spawn.targetEnt = getEnt( spawn.target, "targetname" );	
	}
	
	if ( remoteMissileSpawnArray.size > 0 )
		remoteMissileSpawn = player getBestSpawnPoint( remoteMissileSpawnArray );
	else
		remoteMissileSpawn = undefined;

	if ( isdefined( remoteMissileSpawn ) )
	{	
		startPos = remoteMissileSpawn.origin;	
		targetPos = remoteMissileSpawn.targetEnt.origin;

		vector = vectorNormalize( startPos - targetPos );		
		startPos = ( vector * level.missileRemoteLaunchVert ) + targetPos;
	}
	else
	{
		upVector = (0, 0, level.missileRemoteLaunchVert );
		backDist = level.missileRemoteLaunchHorz;
		targetDist = level.missileRemoteLaunchTargetDist;
		
		forward = AnglesToForward( player.angles );
		startpos = player.origin + upVector + forward * backDist * -1;
		targetPos = player.origin + forward * targetDist;
	}
	
	self util::setUsingRemote( "remote_missile" );
	self util::freeze_player_controls( true );
	player DisableWeaponCycling();
	
	result = self killstreaks::init_ride_killstreak( "qrdrone" );		
	
	if ( result != "success" || level.gameended )
	{
		if ( result != "disconnect" )
		{
			player util::freeze_player_controls( false );
			player killstreaks::clear_using_remote();
			player EnableWeaponCycling();
			killstreakrules::killstreakStop( "remote_missile", team, killstreak_id );
		}

		return false;
	}	

	rocket = MagicBullet( GetWeapon( "remote_missile_missile" ), startpos, targetPos, player );
	rocket.forceOneMissile = true;
	forceAngleVector = vectorNormalize( targetPos - startPos );
	rocket.angles = VectorToAngles( forceAngleVector );
	rocket.targetname = "remote_missile";
	
	rocket killstreaks::configure_team( "remote_missile", killstreak_id, self, undefined, undefined, undefined );
	rocket killstreak_hacking::enable_hacking( "remote_missile", undefined, &HackedPostFunction );
	killstreak_detect::killstreakTargetSet( rocket );
	rocket.hackedHealthUpdateCallback = &hackedHealthUpdate;
	rocket clientfield::set( "enemyvehicle", 1 );
	
	rocket thread handleDamage();
	
	player LinkToMissile( rocket, true, true );
	rocket.owner = player;
	rocket.killcament = player;
	player thread cleanupWaiter( rocket, player.team, killstreak_id );
	
	visionset_mgr::activate( "visionset", "remote_missile_visionset", player, 0, 90000, 0 );	
	player SetModelLodBias( (isdefined(level.remotemissile_lod_bias)?level.remotemissile_lod_bias:12) );
	self clientfield::set_to_player( "fog_bank_2", 1 );
	self clientfield::set( "operating_predator", 1 );
	self killstreaks::play_killstreak_start_dialog( "remote_missile", self.pers["team"], killstreak_id );

	self AddWeaponStat( GetWeapon( "remote_missile" ), "used", 1 );

	rocket thread setup_rockect_map_icon();
	rocket thread watch_missile_kill_z();
	rocket missile_sound_play( player );
	rocket thread missile_brake_timeout_watch();
	rocket thread missile_sound_impact( player, 3750 );
	player thread missile_sound_boost( rocket );
	player thread missile_deploy_watch( rocket );
	player thread remote_missile_game_end_think( rocket, player.team, killstreak_id );
	player thread watch_missile_death( rocket, player.team, killstreak_id );
	player thread sndWatchExplo();

	rocket spawning::create_entity_enemy_influencer( "small_vehicle", rocket.team );

	player util::freeze_player_controls( false );

	player waittill( "Remotemissle_killstreak_done" );

	return true;
}

function hackedHealthUpdate( hacker )
{
	// no need for health update
}

function HackedPostFunction( hacker )	
{
	rocket = self;
	hacker missile_deploy( rocket, true );
}

function setup_rockect_map_icon()
{
	self endon("death");
	wait( 0.1 );
	self  clientfield::set( "remote_missile_fired", ( 1 ) );
}

function watch_missile_kill_z()
{
	if ( !isdefined( level.remotemissile_kill_z ) )
		return;

	rocket = self;
	kill_z = level.remotemissile_kill_z;

	rocket endon( "Remotemissle_killstreak_done" );
	rocket endon( "death" );
	
	while ( rocket.origin[2] > kill_z )
	{		
		wait 0.1; // need to see explosion, so don't wait too long
	}

	rocket Detonate();
}

function watch_missile_death( rocket, team, killstreak_id )
{
	self endon( "Remotemissle_killstreak_done" );
	
	rocket waittill( "death" );

	self thread player_missile_end( rocket, true, true, team, killstreak_id );

	self thread remotemissile_bda_dialog();
	
	self notify( "Remotemissle_killstreak_done" );
	
}

function player_missile_end( rocket, performPlayerKillstreakEnd, unlink, team, killstreak_id )
{
	self notify( "player_missile_end_singleton" );
	self endon ( "player_missile_end_singleton" );
	
	if( isalive( rocket ) )
	{
		rocket spawning::remove_influencers();
		rocket clientfield::set( "remote_missile_fired", 0 );
		rocket Delete();
	}	
	
	self notify( "snd1stPersonExplo" );
	
	if( isdefined( self ) ) 
	{
		self thread destroy_missile_hud();
		
		//Only do this if the killstreak is ending normally
		if( ( isdefined( performPlayerKillstreakEnd ) && performPlayerKillstreakEnd ) )
		{
			self PlayRumbleOnEntity( "grenade_rumble" );
			
			if ( level.gameended == false ) 
			{
				self SendKillstreakDamageEvent( 600 );
				//self thread hud::fade_to_black_for_x_sec( 0, 0.25, 0.1, 0.25 );
			}

			if( isdefined ( rocket ) ) 
			{
				rocket hide();
			}
		}
	
		self clientfield::set( "operating_predator", 0 );
		self clientfield::set_to_player( "fog_bank_2", 0 );
		visionset_mgr::deactivate( "visionset", "remote_missile_visionset", self );
		self SetModelLodBias( 0 );
		
		if( unlink )
			self UnlinkFromMissile();

		self notify( "remotemissile_done" );
		self util::freeze_player_controls( false );
		self killstreaks::clear_using_remote();
		self EnableWeaponCycling();
		
		killstreakrules::killstreakStop( "remote_missile", team, killstreak_id );
	}
}

function missile_brake_timeout_watch()
{
	rocket = self;
	player = rocket.owner;
	
	self endon( "death" );

	self waittill( "missile_brake" );
	
	rocket PlaySound( "wpn_remote_missile_brake_npc" );
	player playlocalsound( "wpn_remote_missile_brake_plr" );
		
	wait( 1.5 );
	
	if( isdefined( self ) )
	{
		self SetMissileBrake( false );
	}
}

function stopOndeath( snd )
{
	self waittill( "death" );
	if( isdefined( snd ) ) 
		snd delete();
}

function cleanupWaiter( rocket, team, killstreak_id )
{
	self endon( "Remotemissle_killstreak_done" );
	
	self util::waittill_any( "joined_team", "joined_spectators", "disconnect" );
	
	self thread player_missile_end( rocket, false, false, team, killstreak_id );

	self notify( "Remotemissle_killstreak_done" );
}

function handleDamage()
{
	self endon ( "death" );
	self endon ( "deleted" );

	self setCanDamage( true );
	self.health = 99999;
	for ( ;; )
	{
		self waittill( "damage", damage, attacker, direction_vec, point, meansOfDeath, tagName, modelName, partName, weapon );
		
		if ( isdefined ( attacker ) && isdefined( self.owner ) ) 
		{
			if ( self.owner util::IsEnemyPlayer( attacker ) )
			{
				challenges::destroyedAircraft( attacker, weapon, true );
				attacker challenges::addFlySwatterStat( weapon, self );
				scoreevents::processScoreEvent( "destroyed_remote_missile", attacker, self.owner, weapon );
				attacker AddWeaponStat( weapon, "destroyed_controlled_killstreak", 1 );
			}
			else
			{
				//Destroyed Friendly Killstreak 
			}
			self.owner SendKillstreakDamageEvent( int(damage) );
		}
		self spawning::remove_influencers();
		self Detonate();
	}
}	

function staticEffect( duration )
{
	self endon ( "disconnect" );
	
	staticBG = newClientHudElem( self );
	staticBG.horzAlign = "fullscreen";
	staticBG.vertAlign = "fullscreen";
	staticBG setShader( "white", 640, 480 );
	staticBG.archive = true;
	staticBG.sort = 10;
	staticBG.immunetodemogamehudsettings = true;

	static = newClientHudElem( self );
	static.horzAlign = "fullscreen";
	static.vertAlign = "fullscreen";
	//static setShader( "tow_filter_overlay_no_signal", 640, 480 );
	static.archive = true;
	static.sort = 20;
	static.immunetodemogamehudsettings = true;

	self clientfield::set( "remote_killstreak_static", 1 );

	wait ( duration );

	self clientfield::set( "remote_killstreak_static", 0 );
	static destroy();
	staticBG destroy();
}

function Rocket_CleanupOnDeath()
{
	entityNumber = self getEntityNumber();
	level.rockets[ entityNumber ] = self;
	self waittill( "death" );	
	
	level.rockets[ entityNumber ] = undefined;
}

function missile_sound_play( player )
{
	self.snd_first = spawn( "script_model", self.origin );
	self.snd_first SetModel( "tag_origin" );
	self.snd_first LinkTo( self );
	self.snd_first SetInvisibleToAll();
	self.snd_first SetVisibleToPlayer( player );
	self.snd_first PlayLoopSound( "wpn_remote_missile_loop_plr", .5 );
	
	self thread stopOndeath( self.snd_first );

	self.snd_third = spawn( "script_model", self.origin );
	self.snd_third SetModel( "tag_origin" );
	self.snd_third LinkTo( self );
	self.snd_third SetVisibleToAll();
	self.snd_third SetInvisibleToPlayer( player );
	self.snd_third PlayLoopSound( "wpn_remote_missile_loop_npc", .2 );
	
	self thread stopOndeath( self.snd_third );
}

function missile_sound_boost( rocket )
{
	self endon( "remotemissile_done" );
	self endon( "joined_team" );
	self endon( "joined_spectators" );
	self endon( "disconnect" );

	self waittill( "missile_boost" );
	rocket PlaySound( "wpn_remote_missile_fire_boost_npc" );
	rocket.snd_third PlayLoopSound( "wpn_remote_missile_boost_npc" );
	
	self playlocalsound( "wpn_remote_missile_fire_boost_plr" );
	rocket.snd_first PlayLoopSound( "wpn_remote_missile_boost_plr" );
	self PlayRumbleOnEntity( "sniper_fire" );
	
	if ( rocket.origin[2] - self.origin[2] > 4000 )
	{
		rocket notify( "stop_impact_sound" );
		rocket thread missile_sound_impact( self, 6250 );
	}
}

function missile_sound_impact( player, distance )
{
	self endon( "death" );
	self endon( "stop_impact_sound" );
	player endon( "disconnect" );
	player endon( "remotemissile_done" );
	player endon( "joined_team" );
	player endon( "joined_spectators" );
	
	for ( ;; )
	{
		if ( self.origin[2] - player.origin[2] < distance )
		{
			self PlaySound( "wpn_remote_missile_inc" );
			return;
		}
		{wait(.05);};
	}
}

function sndWatchExplo()
{
	self endon( "Remotemissle_killstreak_done" );
	self endon( "remotemissile_done" );
	self endon( "joined_team" );
	self endon( "joined_spectators" );
	self endon( "disconnect" );
	self endon( "bomblets_deployed" );
	
	self waittill( "snd1stPersonExplo" );
	self playlocalsound( "wpn_remote_missile_explode_plr" );
}

function missile_sound_deploy_bomblets()
{
	self.snd_first PlayLoopSound( "wpn_remote_missile_loop_plr", .5 );
}

function getValidTargets( rocket, trace, max_targets )
{
	pixbeginevent("remotemissile_getVTs_header");

	targets = [];

	forward = AnglesToForward ( rocket.angles );

	rocketZ = rocket.origin[2];
	mapCenterZ = level.mapCenter[2];
	diff = mapCenterZ - rocketZ;

	ratio = diff / forward[2];

	aimTarget = rocket.origin + forward * ratio;
	rocket.aimTarget = aimTarget;
	
//	/#
//	circle( rocket.aimTarget, REMOTE_MISSILE_TARGETING_RADIUS, (0,1,0), true, true, 2000 );
//	#/
	
	pixendevent();

	pixbeginevent("remotemissile_getVTs_enemies");

	enemies = self GetEnemies();
	
	foreach( player in enemies )
	{
		if( !IsPlayer( player ) )
		{
			continue;
		}
		
		if ( player.ignoreme === true )
		{
			continue;
		}
		
		if ( Distance2DSquared( player.origin, aimTarget) < 600 * 600 && !player HasPerk( "specialty_nokillstreakreticle" ) )
		{
			if ( trace )
			{
				if ( BulletTracePassed( player.origin + (0,0,60), player.origin + (0,0,180), false, player) )
				{
					targets[targets.size] = player;					
				}
			}
			else
			{
				targets[targets.size] = player;
			}
			if( targets.size >= max_targets )
				return targets;
		}
	}

	dogs = GetEntArray( "attack_dog", "targetname" );
		
	foreach( dog in dogs )
	{
		if ( dog.team != self.team && Distance2DSquared( dog.origin, aimTarget) < 600 * 600 )
		{
			if ( trace )
			{
				if ( BulletTracePassed( dog.origin + (0,0,60), dog.origin + (0,0,180), false, dog) )
				{
					targets[targets.size] = dog;					
				}
			}
			else
			{
				targets[targets.size] = dog;
			}
			if( targets.size >= max_targets )
				return targets;
		}
	}
	
	tanks = GetEntArray( "talon", "targetname" );

	foreach( tank in tanks )
	{
		if ( tank.team != self.team && Distance2DSquared( tank.origin, aimTarget) < 600 * 600 )
		{
			if ( trace )
			{
				if ( BulletTracePassed( tank.origin + (0,0,60), tank.origin + (0,0,180), false, tank) )
				{
					targets[targets.size] = tank;					
				}
			}
			else
			{
				targets[targets.size] = tank;
			}
			if( targets.size >= max_targets )
				return targets;
		}
	}
	
	turrets = GetEntArray( "auto_turret", "classname" );
	foreach( turret in turrets )
	{
		if ( turret.team != self.team && Distance2DSquared( turret.origin, aimTarget) < 600 * 600 )
		{
			if ( trace )
			{
				if ( BulletTracePassed( turret.origin + (0,0,60), turret.origin + (0,0,180), false, turret) )
				{
					targets[targets.size] = turret;					
				}
			}
			else
			{
				targets[targets.size] = turret;
			}
			if( targets.size >= max_targets )
				return targets;
		}
	}	
	
	pixendevent();

	return targets;
}

function create_missile_hud( rocket )
{	
	self.missile_target_icons = [];
	
	foreach (player	in level.players)
	{
		if( player == self )
			 continue;
		
		if (level.teamBased && player.team == self.team)
			continue;
		
		index = player.clientId;
		self.missile_target_icons[index] = newClientHudElem( self );
		self.missile_target_icons[index].x = 0;
		self.missile_target_icons[index].y = 0;
		self.missile_target_icons[index].z = 0;
		self.missile_target_icons[index].alpha = 0;
		self.missile_target_icons[index].archived = true;
		self.missile_target_icons[index] setShader( "hud_remote_missile_target", 175, 175 );
		self.missile_target_icons[index] setWaypoint( false );
		self.missile_target_icons[index].hidewheninmenu = true;
		self.missile_target_icons[index].immunetodemogamehudsettings = true;
	}	
	
	for(i=0; i<3; i++ )
	{
		self.missile_target_other[i] = newClientHudElem( self );
		self.missile_target_other[i].x = 0;
		self.missile_target_other[i].y = 0;
		self.missile_target_other[i].z = 0;
		self.missile_target_other[i].alpha = 0;
		self.missile_target_other[i].archived = true;
		self.missile_target_other[i] setShader( "hud_remote_missile_target", 175, 175 );
		self.missile_target_other[i] setWaypoint( false );
		self.missile_target_other[i].hidewheninmenu = true;
		self.missile_target_other[i].immunetodemogamehudsettings = true;
	}
	rocket.iconIndexOther = 0;
	
	self thread targeting_hud_think( rocket );
}

function destroy_missile_hud()
{
	if (isdefined( self.missile_target_icons) )
	{
		foreach (player	in level.players)
		{
			if( player == self )
			{
				continue;
			}

			index = player.clientId;
			if (isdefined(self.missile_target_icons[index]))
			{
				self.missile_target_icons[index] Destroy();
			}
		}
	}
	if (isdefined( self.missile_target_other) )
	{
		for( i=0; i<3; i++)
		{
			if( isdefined( self.missile_target_other[i] ) )
				self.missile_target_other[i] Destroy();
		}
	}
}

function targeting_hud_think( rocket )
{
	self endon( "disconnect" );
	self endon("remotemissile_done"); 
	rocket endon("death");
	level endon ( "game_ended" );
	
	targets = self getValidTargets( rocket, true, 6 );
	framesSinceTargetScan = 0;

	while( true )
	{
		foreach (icon in self.missile_target_icons)
		{
			icon.alpha = 0;
		}
		
		framesSinceTargetScan++;

		if ( framesSinceTargetScan > 5 )
		{
			targets = self getValidTargets( rocket, true, 6 );
			framesSinceTargetScan = 0;
		}

		if (targets.size > 0)
		{
			foreach (target in targets)
			{
				if ( isdefined( target ) == false ) 
					continue;
						
				if ( IsPlayer( target ) )
				{
					if ( isalive( target ) )
					{
						index = target.clientId;
						assert( isdefined( index ) );
						
						self.missile_target_icons[index].x = target.origin[0];
						self.missile_target_icons[index].y = target.origin[1];
						self.missile_target_icons[index].z = target.origin[2] + 47;
						self.missile_target_icons[index].alpha = 1;
					}
				}
				else
				{
					if( !isdefined(target.missileIconIndex))
					{
						target.missileIconIndex = rocket.iconIndexOther;
						rocket.iconIndexOther = (rocket.iconIndexOther + 1) % 3;
					}
					index = target.missileIconIndex;			
					self.missile_target_other[index].x = target.origin[0];
					self.missile_target_other[index].y = target.origin[1];
					self.missile_target_other[index].z = target.origin[2];
					self.missile_target_other[index].alpha = 1;
				}
			}
		}			
		
		wait (0.1);
	}
}

function missile_deploy_watch( rocket )
{
	self endon( "disconnect" );
	self endon("remotemissile_done"); 
	rocket endon("remotemissile_bomblets_launched"); 
	rocket endon("death");
	level endon ( "game_ended" );	
	
	wait ( 0.25 );
	
	self thread create_missile_hud( rocket );
	
	while( true )
	{
		if ( self attackbuttonpressed() )
		{
			self thread missile_deploy( rocket, false );
		}
		else
		{
			{wait(.05);}; 				
		} 
	}
}

function missile_deploy( rocket, hacked )
{
	rocket notify ("remotemissile_bomblets_launched"); 
	waitFrames = 2;
	explosionRadius = 0;
	targets = self getValidTargets( rocket, false, 6 );
	if( targets.size > 0 )
	{
		foreach( target in targets )
		{
			self thread fire_bomblet( rocket, explosionRadius, target, waitFrames );
			waitFrames++;
		}
	}
	
	//bomblet = MagicBullet( GetWeapon( "remote_missile_bomblet" ), rocket.origin, rocket.origin + AnglesToForward ( rocket.angles ) * 1000, self);
	//setup_bomblet( bomblet );
	
	if( rocket.origin[2] - self.origin[2] > 4000 )
	{
		//bomblet thread missile_sound_impact( self, 8000 );
		rocket notify( "stop_impact_sound" );
	}
	if( hacked == true )
	{
		rocket.originalOwner thread hud::fade_to_black_for_x_sec( 0, 0.15, 0, 0, "white" );
		self notify("remotemissile_done");
	}

	rocket clientfield::set( "remote_missile_fired", ( 2 ) );
	for( i = targets.size; i < 6; i++ )
	{
		self thread fire_random_bomblet( rocket, explosionRadius, i % 6, waitFrames );
		waitFrames++;
	}
	
	playfx( level.missileRemoteDeployFX, rocket.origin, anglestoForward( rocket.angles ) );
	self playLocalSound("mpl_rc_exp");
	self PlayRumbleOnEntity( "sniper_fire" );			
	Earthquake( 0.2, 0.2, rocket.origin, 200 );
				
	//still rocket for viewing the bomblets
	rocket Hide();
	rocket setMissileCoasting( true );
	if ( hacked == false )
	{
		self thread hud::fade_to_black_for_x_sec( 0, 0.15, 0, 0, "white" );
	}

	rocket missile_sound_deploy_bomblets();
	self thread bomblet_camera_waiter( rocket );
	self notify( "bomblets_deployed" );

	if ( hacked == true )
	{
		rocket notify( "death" );
	}
	
	return;
}
			
function bomblet_camera_waiter( rocket )
{
	self endon( "disconnect" );
	self endon("remotemissile_done"); 
	rocket endon("death");
	level endon ( "game_ended" );

	delay = GetDvarFloat( "scr_rmbomblet_camera_delaytime", 1.0 );

	self waittill( "bomblet_exploded" );

	wait( delay );

	rocket notify( "death" );
	self notify("remotemissile_done");
}

function setup_bomblet_map_icon()
{
	self endon("death");
	wait( 0.1 );
	self clientfield::set( "remote_missile_bomblet_fired", ( 1 ) );
	self clientfield::set( "enemyvehicle", 1 );
}

function setup_bomblet( bomb )
{
	bomb.team = self.team;

	bomb setTeam( self.team );

	//Send over for the compass icon
	bomb thread setup_bomblet_map_icon();

	bomb.killcamEnt = self;

	bomb thread bomblet_explostion_waiter( self );	
}

function fire_bomblet( rocket, explosionRadius, target, waitFrames )
{
	origin = rocket.origin; 

	targetOrigin = target.origin + (0,0,50);
	
	wait( waitFrames * 0.05 );
	
	if( isdefined( rocket ) )
		origin = rocket.origin;

	bomb = MagicBullet( GetWeapon( "remote_missile_bomblet" ), origin, targetOrigin, self, target, (0,0,30) );

	setup_bomblet( bomb );
}

function fire_random_bomblet( rocket, explosionRadius, quadrant, waitFrames )
{
	origin = rocket.origin;
	angles = rocket.angles;
	owner = rocket.owner;
	aimTarget = rocket.aimtarget;
	
	wait ( waitFrames * 0.05 );
	
	angle = randomIntRange( 10 + ( 60 * quadrant), 50 + ( 60 * quadrant ) );
	radius = randomIntRange( 200, 600 + 100 );
	x =	min( radius, 600 - 50 ) * Cos( angle );
	y = min( radius, 600 - 50 ) * Sin( angle );
	
	bomb = MagicBullet( GetWeapon( "remote_missile_bomblet" ), origin, aimtarget + ( x, y, 0 ), self);
	
	setup_bomblet( bomb );
}

function cleanup_bombs( bomb )
{
	player = self;
	bomb endon( "death" ); 
	
	player util::waittill_any( "joined_team", "joined_spectators", "disconnect" );
	
	if( isdefined( bomb ) )
	{
		bomb clientfield::set( "remote_missile_bomblet_fired", 0 );
		bomb delete();
	}
}

function bomblet_explostion_waiter( player )
{
	player thread cleanup_bombs( self );
	
	player endon( "disconnect" );
	player endon( "remotemissile_done" ); 
	player endon( "death" );
	level endon ( "game_ended" );

	self waittill( "death" );

	player notify( "bomblet_exploded" );
}

function remotemissile_bda_dialog()
{
	if ( isdefined( self.remotemissileBda ) )
	{
		if (self.remotemissileBda === 1)
		{
			bdaDialog = "kill1";
		}
		else if (self.remotemissileBda === 2)
		{
			bdaDialog = "kill2";
		}
		else if (self.remotemissileBda === 3)
		{
			bdaDialog = "kill3";
		}
		else if (isdefined( self.remotemissileBda ) && self.remotemissileBda > 3)
		{
			bdaDialog = "killMultiple";
		}

		self killstreaks::play_pilot_dialog( bdaDialog, "remote_missile", undefined, self.remoteMissilePilotIndex );
	
		self globallogic_audio::play_taacom_dialog( "confirmHit" );
	
	}
	else
	{
		killstreaks::play_pilot_dialog( "killNone", "remote_missile", undefined, self.remoteMissilePilotIndex );
		globallogic_audio::play_taacom_dialog( "confirmMiss" );
	}
	
	self.remotemissileBda = undefined;
}
