#include maps\mp\_utility;
#include common_scripts\utility;


init()
{
	level.killstreakFuncs[ "mp_dam" ] = ::tryUseDamKillstreak;
	level.mapKillStreak = "mp_dam";
	
	level.dam_killstreak_duration = 30;
	/#
		//Used for tuning purposes. Please do not delete.
//		SetDvarIfUninitialized( "scr_dam_killstreak_duration", 30 );
	#/
	
	precacheshader("s1_railgun_hud_reticle_center");	
	precacheshader("s1_railgun_hud_reticle_meter_circ");
	precacheshader("s1_railgun_hud_inner_frame_edge");
	precacheshader("s1_railgun_hud_inner_frame_edge_right");
			
	PreCacheItem( "killstreak_dam_mp" );
	
	PreCacheModel( "mp_dam_large_caliber_turret" );

	level.HUDItem = [];
}

/*
=============
///ScriptDocBegin
"Name: tryUseDamKillstreak( <lifeId> )"
"Summary: the killstreak function added to level.killstreakFuncs[]."
"Module: Entity"
"CallOn: a player"
"MandatoryArg: <lifeId>: "
"Example: "
"SPMP: MP"
///ScriptDocEnd
=============
*/
tryUseDamKillstreak( lifeId, modules )
{
	if ( isDefined( level.mp_dam_player ) )
	{
		self iPrintLnBold( &"MP_DAM_IN_USE" );
		return false;
	}
	
	if ( self isUsingRemote() )
	{
		return false;
	}
	
	if ( self isAirDenied() )
	{
		return false;
	}
	
	if ( self isEMPed() )
	{
		return false;
	}

	if(IsDefined(self.ControllingWarbird)&&self.ControllingWarbird==true)
	{
		self iprintLnBold( &"MP_WARBIRD_ACTIVE" );
		return false;
	}
	
	result = self maps\mp\killstreaks\_killstreaks::initRideKillstreak();
	if ( result != "success" )
		return false;
	self setUsingRemote( "mp_dam" );
	
	result = setMPDamPlayer( self );
	
	// this needs to get set after we say the player is using it because this could get set to true and then they leave the game
	// this fixes a bug where a player calls it, leaves before getting fully in it and then no one else can call it because it thinks it's being used
	if( IsDefined( result ) && result )
	{
		self maps\mp\_matchdata::logKillstreakEvent( "mp_dam", self.origin );
	}
	else
	{
		if ( isUsingRemote() )
			self clearUsingRemote();
	}
	
	return result;
}


/*
=============
///ScriptDocBegin
"Name: setMPDamPlayer( <player> )"
"Summary: kicks off most of the script that controls mp_dam map killstreak functionality."
"Module: Entity"
"CallOn: NA"
"MandatoryArg: <player>: the player who is using the mp_dam map killstreak."
"Example: result = setMPDamPlayer( self );"
"SPMP: MP"
///ScriptDocEnd
=============
*/
setMPDamPlayer( player )
{
	self endon ( "mp_dam_player_removed" );
	
	if( IsDefined( level.mp_dam_player ) )
		return false;
	
	level.mp_dam_player = player;

	player NotifyOnPlayerCommand( "SwitchTurret", "weapnext" );
	player NotifyOnPlayerCommand( "SwitchVisionMode", "+actionslot 1" );
		
	//player openMenu( "ac130timer" );
	
	thread teamPlayerCardSplash( "used_mp_dam", player );
	
	// with the way we do visionsets we need to wait for the clearRideIntro() is done before we set thermal
	player thread waitSetThermal( 1.0 );

	//player thread overlay( player );
	
	if ( getDvarInt( "camera_thirdPerson" ) )
		player setThirdPersonDOF( false );
	
	/#
//		level.dam_killstreak_duration = GetDvarInt( "scr_dam_killstreak_duration", 30 );
	#/

	player SetClientOmnvar( "ui_damturret_countdown", (level.dam_killstreak_duration*1000) + GetTime() ); //UI countdowns automatically subtract the current match time, so we have to add it back here with GetTime().
		
	player thread CycleTurretControl();
	player thread removeMPDamPlayerAfterTime( level.dam_killstreak_duration );
	player thread removeMPDamPlayerOnDisconnect();
	player thread removeMPDamPlayerOnChangeTeams();
	player thread removeMPDamPlayerOnSpectate();
	player thread removeMPDamPlayerOnGameCleanup();
	player thread removeMPDamPlayerOnCommand();

	return true;
}

CycleTurretControl()
{
	self endon ( "mp_dam_player_removed" );
	
	player = self;
	
	if(IsDefined(level.DamTurrets))
	{		
		player EnableSlowAim(.2,.2);
		while(1)
		{
			for( i=0;i<level.DamTurrets.size;i++)
			{
				turret = level.DamTurrets[i];
				
				turret.owner = player;
				turret.team = player.team;
				turret.pers["team"] = player.team;
				if ( level.teamBased )
				{
					turret SetTurretTeam( player.team );
				}
				player.turret = turret;
							    
			    turret setmode( "sentry_manual" );
			    turret SetSentryOwner( player );
			    player thread shotFired( turret );
			    
			    if(i==0)
   					player PlayerLinkWeaponViewToDelta(turret, "tag_player", 0, 60, 30, 5, 58, false );
			    else
			    	player PlayerLinkWeaponViewToDelta(turret, "tag_player", 0, 40, 50, 5, 58, false );
			    
			    player PlayerLinkedSetUseBaseAngleForViewClamp( true );
			
				player RemoteControlTurret(turret,40);
			    //player thread movementAudio( turret );
			    
			    wait .5;
			    
				if(IsDefined(self.DamThermal) && self.DamThermal == true)
					self ThermalVisionOn();	
	
				self SetClientOmnvar( "ui_damturret_toggle", true );
	
				self waittill( "SwitchTurret" );
				
				if(IsDefined(self.DamThermal) && self.DamThermal == true)
					self ThermalVisionOff();
				
				self SetClientOmnvar( "ui_damturret_toggle", false );
	
				player TransitionTurret();
					
				player Unlink();
				player RemoteControlTurretOff(turret);
				
				//reset default turret mode
				turret SetMode( "manual" );
				turret SetTargetEntity( level.DamDefaultAimEnt );
			}
		}
	}	
}	

TransitionTurret()
{
	self VisionSetNakedForPlayer( "black_bw", 0.75 );
	wait .8;
	self revertVisionSetForTurretPlayer( .5 ); // go to default visionset	
}

revertVisionSetForTurretPlayer( time )
{
	AssertEx( isPlayer( self ), "revertVisionSetForPlayer() called on a non player entity" );
	
	if( !isDefined( time ) )
		time = 1;
	if ( IsDefined( level.nukeDetonated ) && isDefined( level.nukeVisionSet )  )
		self VisionSetNakedForPlayer( level.nukeVisionSet, time ); // go to nuke visionset
	else if( isDefined( self.usingRemote ) && isDefined( self.rideVisionSet ) )
		self VisionSetNakedForPlayer( self.rideVisionSet, time ); // go to ride visionset
	else
		self VisionSetNakedForPlayer( "", time ); // go to default visionset
}


waitSetThermal( delay )
{
	self endon( "disconnect" );
	level endon( "mp_dam_player_removed" );

	wait( delay	);

	self VisionSetThermalForPlayer( game["thermal_vision"], 0 );
	self ThermalVisionFOFOverlayOn();
	self SetBlurForPlayer( 1.1, 0 );
	
	//self thread thermalVision();
}

thermalVision()
{
	self endon ( "mp_dam_player_removed" );
//	self endon ( "SwitchTurret" );
	
//	self VisionSetThermalForPlayer( "paris_ac130_thermal", 0.25 );
	
	while ( 1 )
	{
		self.DamThermal = false;
		self waittill( "SwitchVisionMode" );
		self ThermalVisionOn();
		
		self.DamThermal = true;
		self waittill( "SwitchVisionMode" );
		self ThermalVisionOff();
	}
}

/*
=============
///ScriptDocBegin
"Name: createMPDamKillstreakClock()"
"Summary: HUD clock for mp_dam map-based killstreak duration."
"Module: Entity"
"CallOn: the player using the mp_dam map-based killstreak."
"Example: player thread createMPDamKillstreakClock()"
"SPMP: MP"
///ScriptDocEnd
=============
*/
createMPDamKillstreakClock()
{
	level endon( "game_ended" );
	self endon( "disconnect" );
	self endon ( "mp_dam_player_removed" );
	
	self.dam_clock = maps\mp\gametypes\_hud_util::createTimer( "hudsmall", 0.9 );
	self.dam_clock maps\mp\gametypes\_hud_util::setPoint( "CENTER", "CENTER", 0, -145 );
	/#
//		level.dam_killstreak_duration = GetDvarFloat( "scr_dam_killstreak_duration", 30.0 );
	#/
	self.dam_clock setTimer( level.dam_killstreak_duration );
	self.dam_clock.color = ( 1.0, 1.0, 1.0 );
	self.dam_clock.archived = false;
	self.dam_clock.foreground = true;
	
	self thread destroyMPDamKillstreakClock();
}


/*
=============
///ScriptDocBegin
"Name: destroyMPDamKillstreakClock()"
"Summary: cleans up the timer for the mp_dam map-based killstreak HUD."
"Module: Entity"
"CallOn: the player using the mp_dam map-based killstreak."
"Example: player thread destroyMPDamKillstreakClock()"
"SPMP: MP"
///ScriptDocEnd
=============
*/
destroyMPDamKillstreakClock()
{
	self waittill( "mp_dam_player_removed" );
	
	if ( IsDefined( self.dam_clock ) )
	{
		self.dam_clock Destroy();
	}
}

/*
=============
///ScriptDocBegin
"Name: removeMPDamPlayerOnCommand()"
"Summary: removes the dam killstreak player if the player holds down the exit button"
"Module: Entity"
"CallOn: the player controlling the dam map killstreak"
"Example: player thread removeMPDamPlayerOnCommand()"
"SPMP: MP"
///ScriptDocEnd
=============
*/
removeMPDamPlayerOnCommand()
{
	self endon ( "mp_dam_player_removed" );
	
	while ( true )
	{
		button_hold_time = 0;
		while ( self UseButtonPressed() )
		{
			button_hold_time += 0.05;
			if ( button_hold_time > 0.75 )
			{
				level thread removeMPDamPlayer( self, false );
				return;
			}
			wait(0.05);
		}
		wait(0.05);
	}
}


removeMPDamPlayerOnGameCleanup()
{
	self endon ( "mp_dam_player_removed" );
	
	level waittill ( "game_cleanup" );

	level thread removeMPDamPlayer( self, false );
}


removeMPDamPlayerOnDeath()
{
	self endon ( "mp_dam_player_removed" );
	
	self waittill ( "death" );

	level thread removeMPDamPlayer( self, false );
}


removeMPDamPlayerOnDisconnect()
{
	self endon ( "mp_dam_player_removed" );

	self waittill ( "disconnect" );

	level thread removeMPDamPlayer( self, true );
}


removeMPDamPlayerOnChangeTeams()
{
	self endon ( "mp_dam_player_removed" );

	self waittill ( "joined_team" );

	level thread removeMPDamPlayer( self, false);
}


removeMPDamPlayerOnSpectate()
{
	self endon ( "mp_dam_player_removed" );

	self waittill_any ( "joined_spectators", "spawned" );

	level thread removeMPDamPlayer( self, false);
}


removeMPDamPlayerAfterTime( removeDelay )
{
	self endon ( "mp_dam_player_removed" );
	
	if ( self _hasPerk( "specialty_blackbox" ) && IsDefined( self.specialty_blackbox_bonus ) )
	{
		removeDelay *= self.specialty_blackbox_bonus;
	}
	
	maps\mp\gametypes\_hostmigration::waitLongDurationWithHostMigrationPause( removeDelay );
	
	level thread removeMPDamPlayer( self, false );
}


removeMPDamPlayer( player, disconnected )
{
	player notify ( "mp_dam_player_removed" );
	level notify ( "mp_dam_player_removed" );
	
	waittillframeend;
	
	if ( !disconnected )
	{
		player SetClientOmnvar( "ui_damturret_toggle", false );
		player SetBlurForPlayer( 0, 0 );
		player ThermalVisionOff();		
		player ThermalVisionFOFOverlayOff();
		player RemoteControlTurretOff( player.turret );
		player Unlink();
		player clearUsingRemote();		
		player revertVisionSetForPlayer( .5 ); // go to default visionset	
		player DisableSlowAim();

		if ( getDvarInt( "camera_thirdPerson" ) )
			player setThirdPersonDOF( true );

		if ( isDefined( player.darkScreenOverlay ) )
			player.darkScreenOverlay destroy();	
		
		foreach(turret in level.DamTurrets)
		{
			turret SetMode( "manual" );
			turret SetTargetEntity( level.DamDefaultAimEnt );
		}
		
	}
	
	// TODO: this might already be undefined if the player disconnected... need a better solution.
	// we could set it to "true" or something... but we'll have to check places it is used for potential issues with that.
	level.mp_dam_player = undefined;
}


overlay( player )
{
	level.HUDItem[ "thermal_vision" ] = NewClientHudElem( player );
	level.HUDItem[ "thermal_vision" ].x = 200;
	level.HUDItem[ "thermal_vision" ].y = 0;
	level.HUDItem[ "thermal_vision" ].alignX = "left";
	level.HUDItem[ "thermal_vision" ].alignY = "top";
	level.HUDItem[ "thermal_vision" ].horzAlign = "left";
	level.HUDItem[ "thermal_vision" ].vertAlign = "top";
	level.HUDItem[ "thermal_vision" ].fontScale = 2.5;
	level.HUDItem[ "thermal_vision" ] SetText( &"AC130_HUD_FLIR" );
	level.HUDItem[ "thermal_vision" ].alpha = 1.0;

	level.HUDItem[ "enhanced_vision" ] = NewClientHudElem( player );
	level.HUDItem[ "enhanced_vision" ].x = -200;
	level.HUDItem[ "enhanced_vision" ].y = 0;
	level.HUDItem[ "enhanced_vision" ].alignX = "right";
	level.HUDItem[ "enhanced_vision" ].alignY = "top";
	level.HUDItem[ "enhanced_vision" ].horzAlign = "right";
	level.HUDItem[ "enhanced_vision" ].vertAlign = "top";
	level.HUDItem[ "enhanced_vision" ].fontScale = 2.5;
	level.HUDItem[ "enhanced_vision" ] SetText( &"AC130_HUD_OPTICS" );
	level.HUDItem[ "enhanced_vision" ].alpha = 1.0;
	
	player setBlurForPlayer( 1.2, 0 );
}

shotFired( turret )
{
	self endon ( "mp_dam_player_removed" );
	self endon ( "SwitchTurret" );
	for (;;)
	{
		turret waittill( "turret_fire" );
		
		earthquake( 0.25, 1.0, turret.origin, 3500 );
		PlayRumbleOnPosition( "artillery_rumble", turret.origin);
		self thread shotFiredDarkScreenOverlay();

		wait 0.05;
	}
}

shotFiredDarkScreenOverlay()
{
	self endon( "mp_dam_player_removed" );
	self notify( "darkScreenOverlay" );
	self endon( "darkScreenOverlay" );
	
	if ( !isdefined( self.darkScreenOverlay ) )
	{
		self.darkScreenOverlay = NewClientHudElem( self );
		self.darkScreenOverlay.x = 0;
		self.darkScreenOverlay.y = 0;
		self.darkScreenOverlay.alignX = "left";
		self.darkScreenOverlay.alignY = "top";
		self.darkScreenOverlay.horzAlign = "fullscreen";
		self.darkScreenOverlay.vertAlign = "fullscreen";
		self.darkScreenOverlay setshader ( "black", 640, 480 );
		self.darkScreenOverlay.sort = -10;
		self.darkScreenOverlay.alpha = 0.0;
	}
	
	self.darkScreenOverlay.alpha = 0.0;
	self.darkScreenOverlay fadeOverTime( 0.05 );
	self.darkScreenOverlay.alpha = 0.2;
	wait 0.4;
	self.darkScreenOverlay fadeOverTime( 0.8 );
	self.darkScreenOverlay.alpha = 0.0;
}

movementAudio( turret )
{
	self endon ( "mp_dam_player_removed" );
	self endon ( "SwitchTurret" );

	if ( !IsDefined( level.aud ) )
	{
		level.aud = spawnstruct();
	}

	self thread movementAudioCleanup();

	while ( true )
	{
		yaw_rate = turret GetTurretYawRate();	
		yaw_rate = abs( yaw_rate );
	
		pitch_rate = turret GetTurretPitchRate();
		pitch_rate = abs( pitch_rate );

		if ( yaw_rate > 0.1 )
		{
			if ( !IsDefined( level.aud.turretYawLp ) )
			{
				level.aud.turretYawLp = spawn( "script_origin", turret.origin );
				level.aud.turretYawLp PlayLoopSound("wpn_railgun_dam_lat_move_lp");
			}
		}
		else
		{
			if ( IsDefined( level.aud.turretYawLp ) )
			{
				level.aud.turretYawLp StopLoopSound();
				level.aud.turretYawLp Delete();
				level.aud.turretYawLp = undefined;
				turret PlaySound("wpn_railgun_dam_lat_stop");
			}
		}
		
		if ( pitch_rate > 0.1 )
		{
			if ( !IsDefined( level.aud.turretPitchLp ) )
			{
				level.aud.turretPitchLp = spawn( "script_origin", turret.origin );
				level.aud.turretPitchLp PlayLoopSound("wpn_railgun_dam_vert_move_lp");
			}
		}
		else
		{
			if ( IsDefined( level.aud.turretPitchLp ) )
			{
				level.aud.turretPitchLp StopLoopSound();
				level.aud.turretPitchLp Delete();
				level.aud.turretPitchLp = undefined;
				turret PlaySound("wpn_railgun_dam_vert_stop");
			}
		}

		wait 0.05;
	}
}

movementAudioCleanup()
{
	self waittill( "mp_dam_player_removed" );

	if ( IsDefined( level.aud.turretYawLp ) )
	{
		level.aud.turretYawLp StopLoopSound();
		level.aud.turretYawLp Delete();
		level.aud.turretYawLp = undefined;
	}

	if ( IsDefined( level.aud.turretPitchLp ) )
	{
		level.aud.turretPitchLp StopLoopSound();
		level.aud.turretPitchLp Delete();
		level.aud.turretPitchLp = undefined;
	}
}
