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


/************************************************************************************************************/
/*												RADIATION EFFECT											*/
/************************************************************************************************************/
main()
{
	// &&1 mR/hr
	precacheString( &"SCOUTSNIPER_MRHR" );
	// Avoid the radiation zones.\nListen for the clicks of the Geiger counter.
	precacheString( &"SCRIPT_RADIATION_DEATH" );
	precacheShellShock( "radiation_low" );
	precacheShellShock( "radiation_med" );
	precacheShellShock( "radiation_high" );

	foreach ( key, player in level._players )
	{
		player.radiation = spawnstruct();
		player.radiation.super_dose = false;
		player.radiation.inside = false;
		player ent_flag_init( "_radiation_poisoning" );
	}
	run_thread_on_targetname( "radiation", ::updateRadiationTriggers );
	run_thread_on_targetname( "super_radiation", ::super_radiation_trigger );

	array_thread( level._players, ::updateRadiationDosage );
	array_thread( level._players, ::updateRadiationDosimeter );
	array_thread( level._players, ::updateRadiationShock );
	array_thread( level._players, ::updateRadiationBlackOut );
	array_thread( level._players, ::updateRadiationSound );
	array_thread( level._players, ::updateRadiationFlag );
	array_thread( level._players, ::first_radiation_dialogue );
//	array_thread( level.players, ::updateRadiationRatePercent );
}

updateRadiationTriggers()
{
	self.members = 0;

	for ( ;; )
	{
		self waittill( "trigger", player );

		self thread updateRadiationTrigger_perplayer( player );
	}
}

updateRadiationTrigger_perplayer( player )
{
	if ( player.radiation.inside )
		return;

	player.radiation.inside = true;
	player.radiation.triggers[ player.radiation.triggers.size ] = self;

	while ( player isTouching( self ) )
		wait 0.05;

	player.radiation.inside = false;
	player.radiation.triggers = array_remove( player.radiation.triggers, self );
}

super_radiation_trigger()
{
	self waittill( "trigger", player );
	player.radiation.super_dose = true;
}

updateRadiationDosage()
{
	self.radiation.triggers = [];
	self.radiation.rate = 0;
	self.radiation.ratepercent = 0;
	self.radiation.total = 0;
	self.radiation.totalpercent = 0;

	update_frequency = 1;
	min_rate = 0;
	max_rate = 1100000 / ( 60 * update_frequency );	// 60 REM / PH
	max_total = 200000;	// 200 REM

	range = max_rate - min_rate;

	for ( ;; )
	{
		rates = [];
		for ( i = 0 ; i < self.radiation.triggers.size ; i++ )
		{
			trigger = self.radiation.triggers[ i ];

			dist = ( distance( self.origin, trigger.origin ) - 15 );
			rates[ i ] = max_rate - ( max_rate / trigger.radius ) * dist;
		}

		rate = 0;
		for ( i = 0 ; i < rates.size ; i++ )
			rate = rate + rates[ i ];

		if ( rate < min_rate )
			rate = min_rate;

		if ( rate > max_rate )
			rate = max_rate;

		self.radiation.rate = rate;
		self.radiation.ratepercent = ( rate - min_rate ) / range * 100;

		if ( self.radiation.super_dose )
		{
			rate = max_rate;
			self.radiation.ratepercent = 100;
		}

		if ( self.radiation.ratepercent > 25 )
		{
			self.radiation.total += rate;
			self.radiation.totalpercent = self.radiation.total / max_total * 100;
		}

		else if ( self.radiation.ratepercent < 1 && self.radiation.total > 0 )
		{
			self.radiation.total -= 1500;
			if ( self.radiation.total < 0 )
				self.radiation.total = 0;

			self.radiation.totalpercent = self.radiation.total / max_total * 100;
		}

		wait update_frequency;
	}
}

updateRadiationShock()
{
	update_frequency = 1;

	for ( ;; )
	{
		if ( self.radiation.ratepercent >= 75 )
			self shellshock( "radiation_high", 5 );
		else if ( self.radiation.ratepercent >= 50 )
			self shellshock( "radiation_med", 5 );
		else if ( self.radiation.ratepercent > 25 )
			self shellshock( "radiation_low", 5 );

		wait update_frequency;
	}
}

updateRadiationSound()
{
	self thread playRadiationSound();

	for ( ;; )
	{
		if ( self.radiation.ratepercent >= 75 )
			self.radiation.sound = "item_geigercouner_level4";
		else if ( self.radiation.ratepercent >= 50 )
			self.radiation.sound = "item_geigercouner_level3";
		else if ( self.radiation.ratepercent >= 25 )
			self.radiation.sound = "item_geigercouner_level2";
		else if ( self.radiation.ratepercent > 0 )
			self.radiation.sound = "item_geigercouner_level1";
		else
			self.radiation.sound = "none";

		wait 0.05;
	}
}

updateRadiationFlag()
{
	for ( ;; )
	{
		if ( self.radiation.ratepercent > 25 )
			self ent_flag_set( "_radiation_poisoning" );
		else
			self ent_flag_clear( "_radiation_poisoning" );

		wait 0.05;
	}
}

playRadiationSound()
{
	wait .05;

	orgin = spawn( "script_origin", ( 0, 0, 0 ) );
	orgin.origin = self.origin;
	orgin.angles = self.angles;
	orgin linkto( self );

	temp = self.radiation.sound;

	for ( ;; )
	{
		if ( temp != self.radiation.sound )
		{
			orgin stoploopsound();

			if ( isdefined( self.radiation.sound ) && self.radiation.sound != "none" )
				orgin playloopsound( self.radiation.sound );
		}

		temp = self.radiation.sound;

		wait 0.05;
	}
}

updateRadiationRatePercent()
{
	update_frequency = 0.05;

	ratepercent = newClientHudElem( self );
	ratepercent.fontScale = 1.2;
	ratepercent.x = 670;
	ratepercent.y = 350;
	ratepercent.alignX = "right";
	ratepercent.label = "";
	//if you wanna put back in - delete this line
	ratepercent.alpha = 0;

	for ( ;; )
	{
		ratepercent.label = self.radiation.ratepercent;

		wait update_frequency;
	}
}

// set an update rate
// add variance so it is never stuck at a single value
// add background radiation
// add a radiation icon
updateRadiationDosimeter()
{
	min_rate = 0.028;
	max_rate = 100;
	update_frequency = 1;

	range = max_rate - min_rate;
	last_origin = self.origin;

	dosimeter = newClientHudElem( self );
	dosimeter.fontScale = 1.2;
	dosimeter.x = 676;
	dosimeter.y = 360;
	//if you wanna put back in - delete this line
	dosimeter.alpha = 0;

	dosimeter.alignX = "right";
	// &&1 mR/hr
	dosimeter.label = &"SCOUTSNIPER_MRHR";

	dosimeter thread updateRadiationDosimeterColor( self );

	for ( ;; )
	{
		if ( self.radiation.rate <= min_rate )
		{
			variance = randomfloatrange( -0.001, 0.001 );
			dosimeter setValue( min_rate + variance );
			//println( "min_rate: ", min_rate, "variance: ", variance );
		}
		else if ( self.radiation.rate > max_rate )
		{
			dosimeter setValue( max_rate );
			// TODO: Display a warning icon that the meter is beyond it's range
		}
		else
			dosimeter setValue( self.radiation.rate );

		wait update_frequency;
	}
}

updateRadiationDosimeterColor( player )
{
	update_frequency = 0.05;

	for ( ;; )
	{
		colorvalue = 1;
		stepamount = 0.13;

		while ( player.radiation.rate >= 100 )
		{
			if ( colorvalue <= 0 || colorvalue >= 1 )
				stepamount = stepamount * - 1;

			colorvalue = colorvalue + stepamount;

			if ( colorvalue <= 0 )
				colorvalue = 0;

			if ( colorvalue >= 1 )
				colorvalue = 1;

			self.color = ( 1, colorvalue, colorvalue );
			//println( "colorvalue: ", colorvalue );

			wait update_frequency;
		}

		self.color = ( 1, 1, 1 );

		wait update_frequency;
	}
}

// this is to indicate you are near your limit of radiation and are about to pass out
// as you near the last 33%( maybe 50% or 75% ) of your max dosage this will be visible while taking more radiation above a TBD threshold
// doing blurring at the same time as darkening
// should pulse, pulses should get longer closer to death and more frequent
// ramp up intensity and frequency
// smooth out pulsing, sin/cos?
// ramp up the low end of alpha somehow
// change pulse to pulse in/out, check some new values to determine what level to pulse out to
updateRadiationBlackOut()
{
	level endon( "special_op_terminated" );
	self endon( "death" );

	overlay = newClientHudElem( self );
	overlay.x = 0;
	overlay.y = 0;
	overlay setshader( "black", 640, 480 );
	overlay.alignX = "left";
	overlay.alignY = "top";
	overlay.horzAlign = "fullscreen";
	overlay.vertAlign = "fullscreen";
	overlay.alpha = 0;

	min_length = 1;
	max_length = 4;
	min_alpha = .25;
	max_alpha = 1;

	min_percent = 25;
	max_percent = 100;

	fraction = 0;

	for ( ;; )
	{
		while ( self.radiation.totalpercent > 25 && self.radiation.ratepercent > 25 )
		{
			percent_range = max_percent - min_percent;
			fraction = ( self.radiation.totalpercent - min_percent ) / percent_range;

			if ( fraction < 0 )
				fraction = 0;
			else if ( fraction > 1 )
				fraction = 1;

			length_range = max_length - min_length;
			length = min_length + ( length_range * ( 1 - fraction ) );

			alpha_range = max_alpha - min_alpha;
			alpha = min_alpha + ( alpha_range * fraction );

			blur = 7.2 * alpha;
			end_alpha = fraction * 0.5;
			end_blur = 7.2 * end_alpha;

			println( "fraction: ", fraction, " length: ", length, " alpha: ", alpha, " blur: ", blur );

			if ( fraction == 1 )
				break;

			duration = length / 2;

			overlay fadeinBlackOut( duration, alpha, blur, self );
			overlay fadeoutBlackOut( duration, end_alpha, end_blur, self );

			// wait a variable amount based on self.radiation.totalpercent, this is the space in between pulses
			//wait 1;
			wait( fraction * 0.5 );
		}

		if ( fraction == 1 )
			break;

		if ( overlay.alpha != 0 )
			overlay fadeoutBlackOut( 1, 0, 0, self );

		wait 0.05;
	}
	overlay fadeinBlackOut( 2, 1, 6, self );
	self thread radiation_kill();
}
radiation_kill()
{
	self.specialDamage = true;
	self.specialDeath = true;
	self.radiationDeath = true;

	if ( !kill_wrapper() )
		return;
	waittillframeend;

	assert( !isAlive( self ) );
	// Avoid the radiation zones.\nListen for the clicks of the Geiger counter.
	quote = &"SCRIPT_RADIATION_DEATH";
	setdvar( "ui_deadquote", quote );
}

fadeinBlackOut( duration, alpha, blur, player )
{
	//target_blur = 7.2 * alpha;

	self fadeOverTime( duration );
	self.alpha = alpha;
	player setBlurForPlayer( blur, duration );
	wait duration;
}

fadeoutBlackOut( duration, alpha, blur, player )
{
	//target_blur = 7.2 * alpha;

	self fadeOverTime( duration );
	self.alpha = alpha;
	player setBlurForPlayer( blur, duration );
	wait duration;
}

first_radiation_dialogue()
{
	self endon( "death" );

	while ( 1 )
	{
		self ent_flag_wait( "_radiation_poisoning" );

		if ( level._script == "scoutsniper" || level._script == "co_scoutsniper" )
			level thread function_stack( ::radio_dialogue, "scoutsniper_mcm_youdaft" );
		level notify( "radiation_warning" );

		self ent_flag_waitopen( "_radiation_poisoning" );
		wait( 10 );
	}
}
