#include maps/mp/zombies/_zm_stats;
#include common_scripts/utility;
#include maps/mp/_utility;

init()
{
	if ( isDefined( level._uses_retrievable_ballisitic_knives ) && level._uses_retrievable_ballisitic_knives == 1 )
	{
		precachemodel( "t5_weapon_ballistic_knife_projectile" );
		precachemodel( "t5_weapon_ballistic_knife_blade_retrieve" );
	}
}

on_spawn( watcher, player )
{
	player endon( "death" );
	player endon( "disconnect" );
	player endon( "zmb_lost_knife" );
	level endon( "game_ended" );
	self waittill( "stationary", endpos, normal, angles, attacker, prey, bone );
	isfriendly = 0;
	if ( isDefined( endpos ) )
	{
		retrievable_model = spawn( "script_model", endpos );
		retrievable_model setmodel( "t5_weapon_ballistic_knife_blade_retrieve" );
		retrievable_model setowner( player );
		retrievable_model.owner = player;
		retrievable_model.angles = angles;
		retrievable_model.name = watcher.weapon;
		if ( isDefined( prey ) )
		{
			if ( isplayer( prey ) && player.team == prey.team )
			{
				isfriendly = 1;
			}
			else
			{
				if ( isai( prey ) && player.team == prey.team )
				{
					isfriendly = 1;
				}
			}
			if ( !isfriendly )
			{
				retrievable_model linkto( prey, bone );
				retrievable_model thread force_drop_knives_to_ground_on_death( player, prey );
			}
			else
			{
				if ( isfriendly )
				{
					retrievable_model physicslaunch( normal, ( randomint( 10 ), randomint( 10 ), randomint( 10 ) ) );
					normal = ( 0, 0, 1 );
				}
			}
		}
		watcher.objectarray[ watcher.objectarray.size ] = retrievable_model;
		if ( isfriendly )
		{
			retrievable_model waittill( "stationary" );
		}
		retrievable_model thread drop_knives_to_ground( player );
		if ( isfriendly )
		{
			player notify( "ballistic_knife_stationary" );
		}
		else
		{
			player notify( "ballistic_knife_stationary" );
		}
		retrievable_model thread wait_to_show_glowing_model( prey );
	}
}

wait_to_show_glowing_model( prey )
{
	level endon( "game_ended" );
	self endon( "death" );
	wait 2;
	self setmodel( "t5_weapon_ballistic_knife_blade_retrieve" );
}

on_spawn_retrieve_trigger( watcher, player )
{
	player endon( "death" );
	player endon( "disconnect" );
	player endon( "zmb_lost_knife" );
	level endon( "game_ended" );
	player waittill( "ballistic_knife_stationary", retrievable_model, normal, prey );
	if ( !isDefined( retrievable_model ) )
	{
		return;
	}
	trigger_pos = [];
	if ( isDefined( prey ) || isplayer( prey ) && isai( prey ) )
	{
		trigger_pos[ 0 ] = prey.origin[ 0 ];
		trigger_pos[ 1 ] = prey.origin[ 1 ];
		trigger_pos[ 2 ] = prey.origin[ 2 ] + 10;
	}
	else
	{
		trigger_pos[ 0 ] = retrievable_model.origin[ 0 ] + ( 10 * normal[ 0 ] );
		trigger_pos[ 1 ] = retrievable_model.origin[ 1 ] + ( 10 * normal[ 1 ] );
		trigger_pos[ 2 ] = retrievable_model.origin[ 2 ] + ( 10 * normal[ 2 ] );
	}
	pickup_trigger = spawn( "trigger_radius_use", ( trigger_pos[ 0 ], trigger_pos[ 1 ], trigger_pos[ 2 ] ) );
	pickup_trigger setcursorhint( "HINT_NOICON" );
	pickup_trigger.owner = player;
	retrievable_model.retrievabletrigger = pickup_trigger;
	hint_string = &"WEAPON_BALLISTIC_KNIFE_PICKUP";
	if ( isDefined( hint_string ) )
	{
		pickup_trigger sethintstring( hint_string );
	}
	else
	{
		pickup_trigger sethintstring( &"GENERIC_PICKUP" );
	}
	pickup_trigger setteamfortrigger( player.team );
	player clientclaimtrigger( pickup_trigger );
	pickup_trigger enablelinkto();
	if ( isDefined( prey ) )
	{
		pickup_trigger linkto( prey );
	}
	else
	{
		pickup_trigger linkto( retrievable_model );
	}
	if ( isDefined( level.knife_planted ) )
	{
		[[ level.knife_planted ]]( retrievable_model, pickup_trigger, prey );
	}
	retrievable_model thread watch_use_trigger( pickup_trigger, retrievable_model, ::pick_up, watcher.weapon, watcher.pickupsoundplayer, watcher.pickupsound );
	player thread watch_shutdown( pickup_trigger, retrievable_model );
}

debug_print( endpos )
{
/#
	self endon( "death" );
	while ( 1 )
	{
		print3d( endpos, "pickup_trigger" );
		wait 0,05;
#/
	}
}

watch_use_trigger( trigger, model, callback, weapon, playersoundonuse, npcsoundonuse )
{
	self endon( "death" );
	self endon( "delete" );
	level endon( "game_ended" );
	while ( 1 )
	{
		trigger waittill( "trigger", player );
		while ( !isalive( player ) )
		{
			continue;
		}
		while ( !player isonground() )
		{
			continue;
		}
		if ( isDefined( trigger.triggerteam ) && player.team != trigger.triggerteam )
		{
			continue;
		}
		if ( isDefined( trigger.claimedby ) && player != trigger.claimedby )
		{
			continue;
		}
		if ( player usebuttonpressed() && !player.throwinggrenade && !player meleebuttonpressed() )
		{
			if ( isDefined( playersoundonuse ) )
			{
				player playlocalsound( playersoundonuse );
			}
			if ( isDefined( npcsoundonuse ) )
			{
				player playsound( npcsoundonuse );
			}
			player thread [[ callback ]]( weapon, model, trigger );
			return;
		}
		else
		{
		}
	}
}

pick_up( weapon, model, trigger )
{
	current_weapon = self getcurrentweapon();
	if ( current_weapon != weapon )
	{
		clip_ammo = self getweaponammoclip( weapon );
		if ( !clip_ammo )
		{
			self setweaponammoclip( weapon, 1 );
		}
		else
		{
			new_ammo_stock = self getweaponammostock( weapon ) + 1;
			self setweaponammostock( weapon, new_ammo_stock );
		}
	}
	else
	{
		new_ammo_stock = self getweaponammostock( weapon ) + 1;
		self setweaponammostock( weapon, new_ammo_stock );
	}
	self maps/mp/zombies/_zm_stats::increment_client_stat( "ballistic_knives_pickedup" );
	self maps/mp/zombies/_zm_stats::increment_player_stat( "ballistic_knives_pickedup" );
	model destroy_ent();
	trigger destroy_ent();
}

destroy_ent()
{
	if ( isDefined( self ) )
	{
		if ( isDefined( self.glowing_model ) )
		{
			self.glowing_model delete();
		}
		self delete();
	}
}

watch_shutdown( trigger, model )
{
	self waittill_any( "death", "disconnect", "zmb_lost_knife" );
	trigger destroy_ent();
	model destroy_ent();
}

drop_knives_to_ground( player )
{
	player endon( "death" );
	player endon( "zmb_lost_knife" );
	for ( ;; )
	{
		level waittill( "drop_objects_to_ground", origin, radius );
		if ( distancesquared( origin, self.origin ) < ( radius * radius ) )
		{
			self physicslaunch( ( 0, 0, 1 ), vectorScale( ( 0, 0, 1 ), 5 ) );
			self thread update_retrieve_trigger( player );
		}
	}
}

force_drop_knives_to_ground_on_death( player, prey )
{
	self endon( "death" );
	player endon( "zmb_lost_knife" );
	prey waittill( "death" );
	self unlink();
	self physicslaunch( ( 0, 0, 1 ), vectorScale( ( 0, 0, 1 ), 5 ) );
	self thread update_retrieve_trigger( player );
}

update_retrieve_trigger( player )
{
	self endon( "death" );
	player endon( "zmb_lost_knife" );
	if ( isDefined( level.custom_update_retrieve_trigger ) )
	{
		self [[ level.custom_update_retrieve_trigger ]]( player );
		return;
	}
	self waittill( "stationary" );
	trigger = self.retrievabletrigger;
	trigger.origin = ( self.origin[ 0 ], self.origin[ 1 ], self.origin[ 2 ] + 10 );
	trigger linkto( self );
}
