#using scripts\codescripts\struct;

#using scripts\shared\callbacks_shared;
#using scripts\shared\challenges_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\damagefeedback_shared;
#using scripts\shared\killstreaks_shared;
#using scripts\shared\math_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\system_shared;
#using scripts\shared\tweakables_shared;
#using scripts\shared\util_shared;
#using scripts\shared\weapons\_heatseekingmissile;
#using scripts\shared\weapons\_weaponobjects;

#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\killstreaks\_airsupport;
#using scripts\mp\killstreaks\_killstreak_bundles;
#using scripts\mp\killstreaks\_killstreak_detect;
#using scripts\mp\killstreaks\_killstreak_hacking;
#using scripts\mp\killstreaks\_killstreakrules;
#using scripts\mp\killstreaks\_killstreaks;
#using scripts\mp\teams\_teams;
#using scripts\mp\_util;

  
                                                                                                   	  	                                                                    	                     	                 	                                                                         	                       	                                                      	                                                      	                                                       	                                                                                                  	                                                                                                                 	                                                   	                	                                          	                                      	       	  	             	                                                     	                                                                             	                         	                                                                	                                                             	                                                             	                                                                                      	                                                         	                                                         	                                                               	                                                               	                                                   	                                                                	                                                     	                                                	                                                	                                                        	                                                                                                  	                                                                             	                                            	                                                                                    	                                          	                     	                                              	                                        	                 	   
    	   	                                                                                                                                         	                                	                                                                                                                                                                                                                                                                                                                                                                    	        	     	              	    	   	               	                                              	                                                           	                               	                     	                                                                                                           	                                                                 	                                                              	                                                                                                                                             	                            	                                     	                                       	                                                                                                              	   	                  	       	                                                    	                   	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	                                                                                                 	                                    	                                                                                        	           	                        	                                            	                                             	                                                   	                                                             	                                                         	                                                                    	                                                                                                                                                                                                                                	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  	    	         	                                                              	                                                          	                                   	                                   	                                                    	                                       	                                           	     	                                                                                                                                                                                                                                                      	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	                                                               	        	                                                                                                                              	                                                                                                                     	                               	                                                      	                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	   	                                                                                                                                                                                                                                  	                                                                                                                                                                                                                                                                                                                                                                                                                                                   

#precache( "eventstring", "mpl_killstreak_radar" );
#precache( "string", "KILLSTREAK_EARNED_RADAR" );
#precache( "string", "KILLSTREAK_RADAR_INBOUND" );
#precache( "string", "KILLSTREAK_RADAR_NOT_AVAILABLE" );
#precache( "string", "KILLSTREAK_DESTROYED_UAV" );
#precache( "string", "KILLSTREAK_RADAR_HACKED" );

#precache( "fx", "killstreaks/fx_uav_damage_trail" );
#precache( "fx", "killstreaks/fx_uav_lights" ); 
#precache( "fx", "killstreaks/fx_uav_bunner" );


	
#namespace uav;
	
function init()
{	
	if ( level.teamBased )
	{
		foreach( team in level.teams )
		{
			level.activeUAVs[ team ] = 0;
		}
	}
	else
	{	
		level.activeUAVs = [];
	}
	
	level.activePlayerUAVs = [];
	level.spawnedUAVs = [];

	if ( tweakables::getTweakableValue( "killstreak", "allowradar" ) )
	{
		killstreaks::register( "uav", "uav", "killstreak_uav", "uav_used", &ActivateUAV );
		killstreaks::register_strings( "uav", &"KILLSTREAK_EARNED_RADAR", &"KILLSTREAK_RADAR_NOT_AVAILABLE", &"KILLSTREAK_RADAR_INBOUND", undefined, &"KILLSTREAK_RADAR_HACKED" );
		killstreaks::register_dialog( "uav", "mpl_killstreak_radar", "uavDialogBundle", "uavPilotDialogBundle", "friendlyUav", "enemyUav", "enemyUavMultiple", "friendlyUavHacked", "enemyUavHacked", "requestUav", "threatUav" );
	}
	
	level thread UAVTracker();
	
	callback::on_connect( &OnPlayerConnect );
	callback::on_spawned( &OnPlayerSpawned );
	callback::on_joined_team( &OnPlayerJoinedTeam );
	
	setMatchFlag( "radar_allies", 0 );
	setMatchFlag( "radar_axis", 0 );
}

function HackedPreFunction( hacker )
{
	uav = self;
	uav ResetActiveUAV();
}

function ConfigureTeamPost( owner, isHacked )
{
	uav = self;
	uav thread teams::WaitUntilTeamChangeSingleTon( owner, "UAV_watch_team_change", &OnTeamChange, owner.entNum, "delete", "death", "leaving" );
	if ( isHacked == false )
	{
		uav teams::HideToSameTeam();
	}
	else
	{
		uav SetVisibleToAll();
	}
	owner AddActiveUAV();
}

function ActivateUAV()
{
	assert( isdefined( level.players ) );
	
	if ( self killstreakrules::isKillstreakAllowed( "uav", self.team ) == false )
	{
		return false;
	}
	
	killstreak_id = self killstreakrules::killstreakStart( "uav", self.team );
	if (  killstreak_id == -1 )
	{
		return false;
	}
	
	rotator = level.airsupport_rotator;
	attach_angle = -90;
	
	uav = spawn( "script_model", rotator getTagOrigin( "tag_origin" ) );
	if ( !isdefined( level.spawnedUAVs ) ) level.spawnedUAVs = []; else if ( !IsArray( level.spawnedUAVs ) ) level.spawnedUAVs = array( level.spawnedUAVs ); level.spawnedUAVs[level.spawnedUAVs.size]=uav;;

	uav setModel( "veh_t7_drone_uav_enemy_vista" );
	
	uav.targetname = "uav";
	
	uav killstreaks::configure_team( "uav", killstreak_id, self, undefined, undefined, &ConfigureTeamPost );
	uav killstreak_hacking::enable_hacking( "uav", &HackedPreFunction, undefined );
	
	uav clientfield::set( "enemyvehicle", 1 );
	killstreak_detect::killstreakTargetSet( uav );
	
	uav SetDrawInfrared( true );
	
	uav.killstreak_id = killstreak_id;
	uav.leaving = false;
	uav.health = 99999;
	
	uav.maxhealth = ( 700 );
	uav.lowhealth = ( ( 700 ) * 0.5 );
	
	uav SetCanDamage( true );
	uav thread killstreaks::MonitorDamage( "uav", uav.maxhealth, &DestroyUAV, uav.lowhealth, &OnLowHealth, 0, undefined, true );

	uav thread heatseekingmissile::MissileTarget_ProximityDetonateIncomingMissile( "crashing", undefined, true );
	uav.rocketDamage = uav.maxhealth + 1;
	
	minFlyHeight = int( airsupport::getMinimumFlyHeight() );
	zOffset = minFlyHeight + (isdefined(level.uav_z_offset)?level.uav_z_offset:( 2500 ));
	
	angle = randomInt( 360 );
	radiusOffset = (isdefined(level.uav_rotation_radius)?level.uav_rotation_radius:( 4000 )) + randomInt( (isdefined(level.uav_rotation_random_offset)?level.uav_rotation_random_offset:( 1000 )) );
	xOffset = cos( angle ) * radiusOffset;
	yOffset = sin( angle ) * radiusOffset;
	angleVector = vectorNormalize( ( xOffset, yOffset, zOffset ) );
	angleVector = angleVector * zOffset;
	uav linkTo( rotator, "tag_origin", angleVector, ( 0, angle + attach_angle, 0 ) );
	
	self AddWeaponStat( GetWeapon( "uav" ), "used", 1 );

	uav thread killstreaks::WaitForTimeout( "uav", ( 25000 ), &OnTimeout, "delete", "death", "crashing" );
	uav thread killstreaks::WaitForTimecheck( ( ( 25000 ) / 2 ), &OnTimecheck, "delete", "death", "crashing" );
	
	uav thread StartUAVFx();
	
	self killstreaks::play_killstreak_start_dialog( "uav", self.team, killstreak_id );
	
	uav killstreaks::play_pilot_dialog_on_owner( "arrive", "uav", killstreak_id );
	uav thread killstreaks::player_killstreak_threat_tracking( "uav" );
	
	return true;
}

function OnLowHealth( attacker, weapon )
{
	self.is_damaged = true;
	params = level.killstreakBundle["uav"];
	if( isdefined( params.fxLowHealth ) )
		PlayFXOnTag( params.fxLowHealth, self, "tag_origin" );
}

function OnTeamChange( entNum, event )
{
	DestroyUAV( undefined, undefined );
}

function DestroyUAV( attacker, weapon )
{	
	attacker = self [[ level.figure_out_attacker ]]( attacker );
	if( isdefined( attacker ) && ( !isdefined( self.owner ) ||  self.owner util::IsEnemyPlayer( attacker ) ) )
	{
		challenges::destroyedAircraft( attacker, weapon, false );
		scoreevents::processScoreEvent( "destroyed_uav", attacker, self.owner, weapon );
		LUINotifyEvent( &"player_callout", 2, &"KILLSTREAK_DESTROYED_UAV", attacker.entnum );
		attacker challenges::addFlySwatterStat( weapon, self );
	}
	
	if( !self.leaving )
	{
		self RemoveActiveUAV();
		
		self killstreaks::play_destroyed_dialog_on_owner( "uav", self.killstreak_id );
	}
	
	self notify( "crashing" );
	
	self playsound ( "evt_helicopter_midair_exp" );
	
	params = level.killstreakBundle["uav"];
	if( isdefined( params.ksExplosionFX ) )
		PlayFXOnTag( params.ksExplosionFX, self, "tag_origin" );
	
	self StopLoopSound();
	self setModel( "tag_origin" );
	Target_Remove( self );
	self unlink();

	wait( 0.5 );
	
	ArrayRemoveValue( level.spawnedUAVs, self );
	self notify( "delete" );
	self delete();
}

function OnPlayerConnect()
{
	self.entNum = self getEntityNumber();
	
	if ( !level.teambased )
	{
		level.activeUAVs[ self.entNum ] = 0;
	}
	
	level.activePlayerUAVs[ self.entNum ] = 0; // needed for UAV-related kill scores
}

function OnPlayerSpawned()
{
	self endon( "disconnect" );
	if( level.teambased == false || level.multiteam == true )
	{	
		level notify( "uav_update" );
	}
}

function OnPlayerJoinedTeam()
{
	HideAllUAVsToSameTeam();
}

function OnTimeout()
{
	PlayAfterburnerFx();
	
	if( ( isdefined( self.is_damaged ) && self.is_damaged ) )
	{
		PlayFxOnTag( "killstreaks/fx_uav_damage_trail", self, "tag_body" );
	}

	self killstreaks::play_pilot_dialog_on_owner( "timeout", "uav" );
	
	self.leaving = true;
	self RemoveActiveUAV();	
	
	airsupport::Leave( ( 10 ) );
	wait( ( 10 ) );
	
	Target_Remove( self );
	ArrayRemoveValue( level.spawnedUAVs, self );
	self delete();
}

function OnTimecheck()
{
	self killstreaks::play_pilot_dialog_on_owner( "timecheck", "uav", self.killstreak_id );
}

function StartUAVFx()
{
	self endon( "death" );
	wait ( 0.1 );
	
	if( isdefined( self ) )
	{
		PlayFXOnTag( "killstreaks/fx_uav_lights", self, "tag_origin" );	
		PlayFXOnTag( "killstreaks/fx_uav_bunner", self, "tag_origin" );		
		self PlayLoopSound ("veh_uav_engine_loop", 1);		
	}
}

function PlayAfterburnerFx()
{
	self endon( "death" );
	wait ( 0.1 );
	
	if( isdefined( self ) )
	{
		PlayFXOnTag( "killstreaks/fx_uav_bunner", self, "tag_origin" );		
		self StopLoopSound();
		team = util::getOtherTeam( self.team );
		self playsoundtoteam ( "veh_kls_uav_afterburner" , team );
	}
}

function HasUAV( team_or_entnum )
{
	return level.activeUAVs[ team_or_entnum ] > 0;
}

function AddActiveUAV()
{
	if ( level.teamBased )
	{
		assert( isdefined( self.team ) );
		level.activeUAVs[self.team]++;	
	}
	else
	{
		assert( isdefined( self.entNum ) );
		if ( !isdefined( self.entNum ) )
		{
			self.entNum = self GetEntityNumber();
		}
		
		level.activeUAVs[ self.entNum ]++;
	}

	level.activePlayerUAVs[ self.entNum ]++;

	level notify ( "uav_update" );
}

function RemoveActiveUAV()
{
	uav = self;
	uav ResetActiveUAV();
	uav killstreakrules::killstreakStop( "uav", self.originalteam, self.killstreak_id );	
}

function ResetActiveUAV()
{
	if ( level.teamBased )
	{
		level.activeUAVs[self.team]--;
		assert( level.activeUAVs[self.team] >= 0 );
		
		if( level.activeUAVs[self.team] < 0 )
		{
			level.activeUAVs[self.team] = 0;
		}
	}
	else if( isdefined( self.owner ) )
	{
		assert( isdefined( self.owner.entNum ) );
		if( !isdefined( self.owner.entNum ) )
		{
			self.owner.entNum = self.owner getEntityNumber();
		}
		
		level.activeUAVs[self.owner.entNum]--;
		
		assert( level.activeUAVs[self.owner.entNum] >= 0 );
		if( level.activeUAVs[self.owner.entNum] < 0 )
		{
			level.activeUAVs[self.owner.entNum] = 0;
		}
	}
	
	if ( isdefined( self.owner ) )
	{		
		level.activePlayerUAVs[self.owner.entNum]--;
		assert( level.activePlayerUAVs[self.owner.entNum] >= 0 );
	}
	level notify ( "uav_update" );
}

function UAVTracker()
{
	level endon ( "game_ended" );
	
	while( true )
	{
		level waittill ( "uav_update" );
		
		// intentionally keeping both teambased and non-teambased logic for now
		// TODO: one "might" be able to change it to teambased only; when trying to do so, watch for knock-on effects

		if( level.teamBased )
		{
			foreach( team in level.teams )
			{
				activeUAVs = level.activeUAVs[ team ];
				activeUAVsAndSatellites = activeUAVs + ( ( isdefined( level.activeSatellites ) ) ? level.activeSatellites[ team ] : 0 );
			
				SetTeamSpyplane( team, int( min( activeUAVs, 2 ) ) );
				util::set_team_radar( team, ( activeUAVsAndSatellites > 0 ) );
			}
		}
		else
		{
			for( i = 0; i < level.players.size; i++ )
			{
				player = level.players[ i ];
				
				assert( isdefined( player.entNum ) );
				if( !isdefined( player.entNum ) )
				{
					player.entNum = player getEntityNumber();
				}
				
				activeUAVs = level.activeUAVs[ player.entNum ];
				activeUAVsAndSatellites = activeUAVs + ( ( isdefined( level.activeSatellites ) ) ? level.activeSatellites[ player.entnum ] : 0 );

				player SetClientUIVisibilityFlag( "radar_client", ( activeUAVsAndSatellites > 0  ) );
				player.hasSpyplane = int( min( activeUAVs, 2 ) );
			}
		}
	}
}

function HideAllUAVsToSameTeam()
{
	foreach( uav in level.spawnedUAVs )
	{
		if ( isdefined( uav ) )
		{
			
			uav teams::HideToSameTeam();
		}
	}
}