#using scripts\codescripts\struct;

#using scripts\shared\math_shared;
#using scripts\shared\statemachine_shared;
#using scripts\shared\callbacks_shared;
#using scripts\shared\clientfield_shared;
#using scripts\shared\system_shared;
#using scripts\shared\array_shared;
#using scripts\shared\util_shared;
#using scripts\shared\ai_shared;

#using scripts\shared\vehicle_shared;
#using scripts\shared\vehicle_death_shared;
#using scripts\shared\vehicle_ai_shared;
#using scripts\shared\ai\systems\blackboard;
#using scripts\shared\ai\blackboard_vehicle;
#using scripts\shared\ai\systems\ai_interface;

    	   	                                                                                                                                         	                                	                                                                                                                                                                                                                                                                                                                                                                    	        	     	              	    	   	               	                                              	                                                           	                               	                     	                                                                                                           	                                                                 	                                                              	                                                                                                                                             	                            	                                     	                                       	                                                                                                              	   	                  	       	                                                    	                   	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	                                                                                                 	                                    	                                                                                        	           	                        	                                            	                                             	                                                   	                                                             	                                                         	                                                                    	                                                                                                                                                                                                                                	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  	    	         	                                                              	                                                          	                                   	                                   	                                                    	                                       	                                           	     	                                                                                                                                                                                                                                                      	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	                                                               	        	                                                                                                                              	                                                                                                                     	                               	                                                      	                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	   	                                                                                                                                                                                                                                  	                                                                                                                                                                                                                                                                                                                                                                                                                                                   
       
                                                                                                            	  	  	              	   	                                                                                                                                       	                                                                                                                                                            	                                                                                                                                                                

                                                                  	                             	  	                                      
           	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              	  	                                 	                  	    	                                                      	   	        	                                                                         	                      	             	                                                                                                                                       	  	                                                                                                          	     	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	                                                                                                      	                                                                                                     	                                                                                                     	                                                                                                	     	                                                                                                                                                                                                                                                                                                                                                                                                                                	     	    	                                                                                                                                    	                      	              	  	             	  
#using scripts\shared\ai\zombie_utility;









	
//reduce these defines to have the parasite make more movements close together





	



	
#namespace parasite;
	
function autoexec __init__sytem__() {     system::register("parasite",&__init__,undefined,undefined);    }

#using_animtree( "generic" );	
	
function __init__()
{	
	vehicle::add_main_callback( "parasite", &parasite_initialize );
	
	clientfield::register( "vehicle", "parasite_tell_fx", 1, 1, "int" );
	clientfield::register( "vehicle", "parasite_secondary_deathfx", 1, 1, "int" );
	clientfield::register( "toplayer", "parasite_damage", 1, 1, "counter" );
	
	callback::on_spawned( &parasite_damage );
	
	ai::RegisterMatchedInterface(
		"parasite",
		"firing_rate",
		"slow",
		array( "slow", "medium", "fast" ) );
}

function parasite_damage()
{
	self notify( "parasite_damage_thread" );
	self endon( "parasite_damage_thread" );
	
	self endon( "death" );
	
	while ( true )
	{
		self waittill( "damage", n_ammount, e_attacker );
		
		if ( IsDefined( e_attacker ) && ( isdefined( e_attacker.is_parasite ) && e_attacker.is_parasite ) && !( isdefined( e_attacker.squelch_damage_overlay ) && e_attacker.squelch_damage_overlay ) )
		{
			self clientfield::increment_to_player( "parasite_damage" );
		}
	}
}

function private is_target_valid( target )
{
	if( !IsDefined( target ) ) 
	{
		return false; 
	}

	if( !IsAlive( target ) )
	{
		return false; 
	} 
	
	if( IsPlayer( target ) && target.sessionstate == "spectator" )
	{
		return false; 
	}

	if( IsPlayer( target ) && target.sessionstate == "intermission" )
	{
		return false; 
	}
	
	if( ( isdefined( target.ignoreme ) && target.ignoreme ) )
	{
		return false;
	}

	if( target IsNoTarget() )
	{
		return false;
	}

	if( IsDefined( self.is_target_valid_cb ) )
	{
		return self [[ self.is_target_valid_cb ]]( target );
	}
	
	return true; 
}

function get_parasite_enemy()
{
	parasite_targets = GetPlayers();
	least_hunted = parasite_targets[0];
	for( i = 0; i < parasite_targets.size; i++ )
	{
		if ( !isdefined( parasite_targets[i].hunted_by ) )
		{
			parasite_targets[i].hunted_by = 0;
		}

		if( !is_target_valid( parasite_targets[i] ) )
		{
			continue;
		}

		if( !is_target_valid( least_hunted ) )
		{
			least_hunted = parasite_targets[i];
		}
			
		if( parasite_targets[i].hunted_by < least_hunted.hunted_by )
		{
			least_hunted = parasite_targets[i];
		}

	}
	// do not return the default first player if he is invalid
	if( !is_target_valid( least_hunted ) )
	{
		return undefined;
	}
	else
	{
		return least_hunted;
	}
}

function set_parasite_enemy( enemy )
{
	if( !is_target_valid( enemy ) )
	{
		return;
	}
	
	if( IsDefined( self.parasiteEnemy ) )
	{
		if( !IsDefined( self.parasiteEnemy.hunted_by ) )
		{
			self.parasiteEnemy.hunted_by = 0;
		}
		if( self.parasiteEnemy.hunted_by > 0 )
		{
			self.parasiteEnemy.hunted_by--;
		}
	}
	
	self.parasiteEnemy = enemy;
	if( !IsDefined( self.parasiteEnemy.hunted_by ) )
	{
		self.parasiteEnemy.hunted_by = 0;
	}
	self.parasiteEnemy.hunted_by++;
	self SetLookAtEnt( self.parasiteEnemy );
	self SetTurretTargetEnt( self.parasiteEnemy );
}

function private parasite_target_selection()
{
	self endon( "change_state" );
	self endon( "death" );
	
	for( ;; )
	{
		if ( ( isdefined( self.ignoreall ) && self.ignoreall ) )
		{
			wait 0.5;
			continue;
		}
		
		if( is_target_valid( self.parasiteEnemy ) )
		{
			wait 0.5;
			continue;
		}
		//decide who the enemy should be
		target = get_parasite_enemy();

		if( !isDefined( target ) )
		{
			self.parasiteEnemy = undefined;		
		}
		else
		{
			self.parasiteEnemy = target;
			//update hunted_by
			self.parasiteEnemy.hunted_by += 1;
			self SetLookAtEnt( self.parasiteEnemy );
			self SetTurretTargetEnt( self.parasiteEnemy );
		}

		wait 0.5;
	}
}

function parasite_initialize()
{
	self useanimtree( #animtree );
	
	// AI SPECIFIC INITIALIZATION
	blackboard::CreateBlackBoardForEntity( self );
	self Blackboard::RegisterVehicleBlackBoardAttributes();
	ai::CreateInterfaceForEntity( self );
	
	Blackboard::RegisterBlackBoardAttribute(self,"_parasite_firing_rate","slow",&getParasiteFiringRate);   if( IsActor(self) )    {    /#self TrackBlackBoardAttribute("_parasite_firing_rate");#/    };

	self.health = self.healthdefault;

	self vehicle::friendly_fire_shield();

	self EnableAimAssist();
	self SetNearGoalNotifyDist( 25 );
	
	self SetDrawInfrared( true );
	
	self.fovcosine = 0;
	self.fovcosinebusy = 0;

	self.vehAirCraftCollisionEnabled = true;

	assert( isdefined( self.scriptbundlesettings ) );

	self.settings = struct::get_script_bundle( "vehiclecustomsettings", self.scriptbundlesettings );
	self.goalRadius = 999999;
	self.goalHeight = 4000;
	self SetGoal( self.origin, false, self.goalRadius, self.goalHeight );
	
	self.is_parasite = true;

	self thread vehicle_ai::nudge_collision();
	
	if( IsDefined( level.vehicle_initializer_cb ) )
	{
    	[[level.vehicle_initializer_cb]]( self );
	}
	
	defaultRole();
}

function defaultRole()
{
	self vehicle_ai::init_state_machine_for_role( "default" );

    self vehicle_ai::get_state_callbacks( "combat" ).enter_func = &state_combat_enter;
    self vehicle_ai::get_state_callbacks( "combat" ).update_func = &state_combat_update;

    self vehicle_ai::get_state_callbacks( "death" ).update_func = &state_death_update;
    
    self vehicle_ai::call_custom_add_state_callbacks();
    
	vehicle_ai::StartInitialState( "combat" );
}

// ----------------------------------------------
//BB getter functions
// ----------------------------------------------
function getParasiteFiringRate()
{
	return self ai::get_behavior_attribute( "firing_rate" );
}

// ----------------------------------------------
// State: death
// ----------------------------------------------
function state_death_update( params )
{
	self endon( "death" );
	
	self ASMRequestSubstate( "death@stationary" );
	
	if( IsDefined( self.parasiteEnemy ) && IsDefined( self.parasiteEnemy.hunted_by ) )
	{
		self.parasiteEnemy.hunted_by--;
	}
	   	
	self SetPhysAcceleration( ( 0, 0, -300 ) );
	self.vehcheckforpredictedcrash = true;
	
	self thread vehicle_death::death_fx();
	self playsound( "zmb_parasite_explo" );
	
	self util::waittill_notify_or_timeout( "veh_predictedcollision", 4.0 );
	
	self clientfield::set( "parasite_secondary_deathfx", 1 );
	
	//make sure the client gets a chance to play the second fx before deleting
	wait 0.2;
	
	self Delete();
}

// ----------------------------------------------
// State: combat
// ----------------------------------------------
function state_combat_enter( params )
{
	if ( IsDefined( self.owner ) && IsDefined( self.owner.enemy ) )
	{
		self.parasiteEnemy = self.owner.enemy;
	}
	self thread parasite_target_selection();
}

function state_combat_update( params )
{
	self endon( "change_state" );
	self endon( "death" );

	lastTimeChangePosition = 0;
	self.shouldGotoNewPosition = false;
	self.lastTimeTargetInSight = 0;
	self.lastTimeJuked = false;
	
	//request movement animations
	self ASMRequestSubstate( "locomotion@movement" );
	
	for( ;; )
	{
		if( IsDefined( self._override_parasite_combat_speed ) )
		{
			self SetSpeed( self._override_parasite_combat_speed );
		}
		else
		{
			self SetSpeed( self.settings.defaultMoveSpeed );
		}
		
		if ( ( isdefined( self.inpain ) && self.inpain ) )
		{
			wait 0.1;
		}
		else if ( !IsDefined( self.parasiteEnemy ) )
		{
			//no enemy, do nothing
			wait( 0.25 );
		}
		else
		{
			if( self.goalforced )
			{
				returnData = [];
				returnData[ "origin" ] = self GetClosestPointOnNavVolume( self.goalpos, 100 );
				returnData[ "centerOnNav" ] = IsPointInNavVolume( self.origin, "navvolume_small" );
			}
			//prevent two consecutive forward jukes, and force juke if path was interrupted ( possibly due to collision )
			else if( ( RandomInt( 100 ) < self.settings.jukeprobability && !( isdefined( self.lastTimeJuked ) && self.lastTimeJuked ) ) || ( isdefined( self._override_juke ) && self._override_juke ) )
			{
				returnData = GetNextMovePosition_forwardjuke();
				self.lastTimeJuked = true;
				self._override_juke = undefined;
			}
			else
			{
				returnData = GetNextMovePosition_tactical();
				self.lastTimeJuked = false;
			}
			self.current_pathto_pos = returnData[ "origin" ];
			if ( IsDefined( self.current_pathto_pos ) )
			{
				if( IsDefined( self.stuckTime ) )
				{
					self.stuckTime = undefined;
				}
				if ( self SetVehGoalPos( self.current_pathto_pos, true, returnData[ "centerOnNav" ] ) )
				{
					self thread path_update_interrupt();
					
					//AUDIO: Was on JUST the juke, but I've moved it for any movement to make it more interesting
					self playsound( "zmb_vocals_parasite_juke" );
					
					self vehicle_ai::waittill_pathing_done( 5 );
				}
				else
				{
					//failsafe, cannot pathfind
					wait( 0.1 );
				}
			}
			else
			{
				if( !( isdefined( returnData[ "centerOnNav" ] ) && returnData[ "centerOnNav" ] ) )
				{
					//not on navmesh, no valid goto points, kill parasite as failsafe
					if( !IsDefined( self.stuckTime ) )
					{
						self.stuckTime = GetTime();
					}
					if( GetTime() - self.stuckTime > 10000 )
					{
						self DoDamage( self.health + 100, self.origin );
					}
				}
			}
			
			if( ( isdefined( self.lastTimeJuked ) && self.lastTimeJuked ) )
			{
				if( RandomInt( 100 ) < 50 && IsDefined( self.parasiteEnemy ) && Distance2DSquared( self.origin, self.parasiteEnemy.origin ) < ( (64) * (64) ) )
				{
					//parasite melee bite
					self.parasiteEnemy DoDamage( self.settings.meleedamage, self.parasiteEnemy.origin, self );
				}
				else
				{
					self fire_pod_logic( self.lastTimeJuked );
				}
			}
			else
			{
				if( RandomInt( 100 ) < 30 )
				{
					self fire_pod_logic( self.lastTimeJuked );
				}
			}
		}
	}
}

function fire_pod_logic( choseToJuke )
{
	if( IsDefined( self.parasiteEnemy ) && self VehCanSee( self.parasiteEnemy ) && Distance2DSquared( self.parasiteEnemy.origin, self.origin ) < ( (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) * (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) ) )
	{	
		//switch to fire animation
		self ASMRequestSubstate( "fire@stationary" );
		
		//do the tell		
		self PlaySound( "zmb_vocals_parasite_preattack" );
		self clientfield::set( "parasite_tell_fx", 1 );		
		
		//reached the point in the animation to adjust the turret
		self waittill( "pre_fire" );
		
		if( IsDefined( self.parasiteEnemy ) && self VehCanSee( self.parasiteEnemy ) && Distance2DSquared( self.parasiteEnemy.origin, self.origin ) < ( (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) * (0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax ) * 3) ) )
		{
			//fire the projectile at the predicted player position
			self SetTurretTargetEnt( self.parasiteEnemy, self.parasiteEnemy GetVelocity() * 0.3 );
		}
		
		self vehicle_ai::waittill_asm_complete( "fire@stationary", 5 );
		
		//switch back to locomotion
		self ASMRequestSubstate( "locomotion@movement" );
		
		//cleanup the fx
		self clientfield::set( "parasite_tell_fx", 0 );
		
		if( !choseToJuke )
		{
			wait RandomFloatRange( 0.25, 0.5 );
		}
	}
	else
	{
		wait RandomFloatRange( 1, 2 );
	}
}

function GetNextMovePosition_tactical() // has self.parasiteEnemy
{
	self endon( "change_state" );
	self endon( "death" );
	
	// distance based multipliers
	selfDistToTarget = Distance2D( self.origin, self.parasiteEnemy.origin );

	goodDist = 0.5 * ( self.settings.engagementDistMin + self.settings.engagementDistMax );

	closeDist = 1.2 * goodDist;
	farDist = 3 * goodDist;

	queryMultiplier = MapFloat( closeDist, farDist, 1, 3, selfDistToTarget );
	
	//the preferred height range should be half the max possible difference to not exceed valid heights for points near the goalheight
	preferedHeightRange = 0.5 * ( self.settings.engagementHeightMax - self.settings.engagementHeightMin );
	randomness = 30;

	// query
	queryResult = PositionQuery_Source_Navigation( self.origin, 75, 225 * queryMultiplier, 75, 20 * queryMultiplier, self, 20 * queryMultiplier );
	//turn off collision, we are not on the navvolume
	if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
	{
		self.vehAirCraftCollisionEnabled = false;
	}
	else
	{
		self.vehAirCraftCollisionEnabled = true;
	}
	// filter
	PositionQuery_Filter_DistanceToGoal( queryResult, self );
	vehicle_ai::PositionQuery_Filter_OutOfGoalAnchor( queryResult );
	self vehicle_ai::PositionQuery_Filter_EngagementDist( queryResult, self.parasiteEnemy, self.settings.engagementDistMin, self.settings.engagementDistMax );

	goalHeight = self.parasiteEnemy.origin[2] + 0.5 * ( self.settings.engagementHeightMin + self.settings.engagementHeightMax );	
	
	// score points
	best_point = undefined;
	best_score = -999999;
	trace_count = 0;
	foreach ( point in queryResult.data )
	{
		if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
		{
			if( SightTracePassed( self.origin, point.origin, false, undefined ) )
			{
				trace_count++;
				if( trace_count > 3 )
				{
					{wait(.05);};
					trace_count = 0;
				}
				if( !BulletTracePassed( self.origin, point.origin, false, self ) )
				{
					continue;
				}
			}
			else
			{
				continue;
			}
		}
		
		/#    if ( !isdefined( point._scoreDebug ) )    {     point._scoreDebug = [];    }    point._scoreDebug[ "random" ] = randomFloatRange( 0, randomness );    #/    point.score += randomFloatRange( 0, randomness );;

		/#    if ( !isdefined( point._scoreDebug ) )    {     point._scoreDebug = [];    }    point._scoreDebug[ "engagementDist" ] = -point.distAwayFromEngagementArea;    #/    point.score += -point.distAwayFromEngagementArea;;
		
		// height
		distFromPreferredHeight = abs( point.origin[2] - goalHeight );
		if ( distFromPreferredHeight > preferedHeightRange )
		{
			heightScore = MapFloat( 0, 500, 0, 2000, distFromPreferredHeight );
			/#    if ( !isdefined( point._scoreDebug ) )    {     point._scoreDebug = [];    }    point._scoreDebug[ "height" ] = -heightScore;    #/    point.score += -heightScore;;
		}
		
		if ( point.score > best_score )
		{
			best_score = point.score;
			best_point = point;
		}
	}
	self vehicle_ai::PositionQuery_DebugScores( queryResult );

	/#
	if ( ( isdefined( GetDvarInt("hkai_debugPositionQuery") ) && GetDvarInt("hkai_debugPositionQuery") ) )
	{
		recordLine( self.origin, best_point.origin, (0.3,1,0) );
		recordLine( self.origin, self.parasiteEnemy.origin, (1,0,0.4) );
	}
#/
	returnData = [];
	returnData[ "origin" ] = ( ( IsDefined( best_point ) ) ? best_point.origin : undefined );
	returnData[ "centerOnNav" ] = queryResult.centerOnNav;
	return returnData;
}


function GetNextMovePosition_forwardjuke() // has self.parasiteEnemy
{
	self endon( "change_state" );
	self endon( "death" );
	
	// distance based multipliers
	selfDistToTarget = Distance2D( self.origin, self.parasiteEnemy.origin );
	
	goodDist = 0.5 * ( self.settings.forwardJukeEngagementDistMin + self.settings.forwardJukeEngagementDistMax );

	closeDist = 1.2 * goodDist;
	farDist = 3 * goodDist;

	queryMultiplier = MapFloat( closeDist, farDist, 1, 3, selfDistToTarget );
	
	preferedHeightRange = 0.5 * ( self.settings.forwardJukeEngagementHeightMax - self.settings.forwardJukeEngagementHeightMin );
	randomness = 30;

	// query
	queryResult = PositionQuery_Source_Navigation( self.origin, 75, 300 * queryMultiplier, 75, 20 * queryMultiplier, self, 20 * queryMultiplier );
	if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
	{
		self.vehAirCraftCollisionEnabled = false;
	}
	else
	{
		self.vehAirCraftCollisionEnabled = true;
	}
	// filter
	PositionQuery_Filter_DistanceToGoal( queryResult, self );
	vehicle_ai::PositionQuery_Filter_OutOfGoalAnchor( queryResult );
	self vehicle_ai::PositionQuery_Filter_EngagementDist( queryResult, self.parasiteEnemy, self.settings.forwardJukeEngagementDistMin, self.settings.forwardJukeEngagementDistMax );

	goalHeight = self.parasiteEnemy.origin[2] + 0.5 * ( self.settings.forwardJukeEngagementHeightMin + self.settings.forwardJukeEngagementHeightMax );	
	
	// score points
	best_point = undefined;
	best_score = -999999;
	trace_count = 0;
	
	foreach ( point in queryResult.data )
	{
		if( !( isdefined( queryResult.centerOnNav ) && queryResult.centerOnNav ) )
		{
			if( SightTracePassed( self.origin, point.origin, false, undefined ) )
			{
				trace_count++;
				if( trace_count > 3 )
				{
					{wait(.05);};
					trace_count = 0;
				}
				if( !BulletTracePassed( self.origin, point.origin, false, self ) )
				{
					continue;
				}
			}
			else
			{
				continue;
			}
		}
		
		/#    if ( !isdefined( point._scoreDebug ) )    {     point._scoreDebug = [];    }    point._scoreDebug[ "random" ] = randomFloatRange( 0, randomness );    #/    point.score += randomFloatRange( 0, randomness );;
		
		/#    if ( !isdefined( point._scoreDebug ) )    {     point._scoreDebug = [];    }    point._scoreDebug[ "engagementDist" ] = -point.distAwayFromEngagementArea;    #/    point.score += -point.distAwayFromEngagementArea;;
		
		// height
		distFromPreferredHeight = abs( point.origin[2] - goalHeight );
		if ( distFromPreferredHeight > preferedHeightRange )
		{
			heightScore = MapFloat( 0, 500, 0, 2000, distFromPreferredHeight );
			/#    if ( !isdefined( point._scoreDebug ) )    {     point._scoreDebug = [];    }    point._scoreDebug[ "height" ] = -heightScore;    #/    point.score += -heightScore;;
		}
		
		if ( point.score > best_score )
		{
			best_score = point.score;
			best_point = point;
		}
	}
	self vehicle_ai::PositionQuery_DebugScores( queryResult );

	/#
	if ( ( isdefined( GetDvarInt("hkai_debugPositionQuery") ) && GetDvarInt("hkai_debugPositionQuery") ) )
	{
		recordLine( self.origin, best_point.origin, (0.3,1,0) );
		recordLine( self.origin, self.parasiteEnemy.origin, (1,0,0.4) );
	}
#/
	
	returnData = [];
	returnData[ "origin" ] = ( ( IsDefined( best_point ) ) ? best_point.origin : undefined );
	returnData[ "centerOnNav" ] = queryResult.centerOnNav;
	return returnData;
}

function path_update_interrupt()
{
	self endon( "death" );
	self endon( "change_state" );
	self endon( "near_goal" );
	self endon( "reached_end_node" );

	wait 1;
	
	while( 1 )
	{
		if( isdefined( self.current_pathto_pos ) )
		{
			if( distance2dSquared( self.current_pathto_pos, self.goalpos ) > ( (self.goalradius) * (self.goalradius) ) )
			{
				wait 0.2;
				self._override_juke = true;
				self notify( "near_goal" );
			}
		}
		wait 0.2;
	}
}


// ----------------------------------------------
// pain/hit reaction
// ----------------------------------------------
function drone_pain_for_time( time, stablizeParam, restoreLookPoint )
{
	self endon( "death" );
	
	self.painStartTime = GetTime();

	if ( !( isdefined( self.inpain ) && self.inpain ) )
	{
		self.inpain = true;
		
		self PlaySound( "zmb_vocals_parasite_pain" );

		while ( GetTime() < self.painStartTime + time * 1000 )
		{
			self SetVehVelocity( self.velocity * stablizeParam );
			self SetAngularVelocity( self GetAngularVelocity() * stablizeParam );
			wait 0.1;
		}

		if ( isdefined( restoreLookPoint ) )
		{
			restoreLookEnt = Spawn( "script_model", restoreLookPoint );
			restoreLookEnt SetModel( "tag_origin" );

			self ClearLookAtEnt();
			self SetLookAtEnt( restoreLookEnt );
			self setTurretTargetEnt( restoreLookEnt );
			wait 1.5;

			self ClearLookAtEnt();
			self ClearTurretTarget();
			restoreLookEnt delete();
		}

		self.inpain = false;
	}
}

function drone_pain( eAttacker, damageType, hitPoint, hitDirection, hitLocationInfo, partName )
{
	if ( !( isdefined( self.inpain ) && self.inpain ) )
	{
		yaw_vel = math::randomSign() * RandomFloatRange( 280, 320 );

		ang_vel = self GetAngularVelocity();
		ang_vel += ( RandomFloatRange( -120, -100 ), yaw_vel, RandomFloatRange( -200, 200 ) );
		self SetAngularVelocity( ang_vel );

		self thread drone_pain_for_time( 0.8, 0.7 );
	}
}