#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include common_scripts\utility;
#include demon\_utils;

init()
{
	precacheItem( "defaultweapon_mp" ); // hardpoint weapon

	precacheItem( "airstrike_mp" );

	// Free weapon files
	/*
	precacheItem( "artillery_mp" ); 
	precacheItem( "helicopter_mp" ); 
	precacheItem( "radar_mp" );
	*/
	
	// carepack shaders
	precacheShader( "waypoint_carepack_uav" );
	precacheShader( "waypoint_carepack_counter_uav" );
	precacheShader( "waypoint_carepack_airstrike" );
	precacheShader( "waypoint_carepack_sentrygun" );
	precacheShader( "waypoint_carepack_littlebird" );
	precacheShader( "waypoint_carepack_helicopter" );
	precacheShader( "waypoint_carepack_harrier" );
	precacheShader( "waypoint_carepack_deathmachine" );
	precacheShader( "waypoint_carepack_stealth" );
	precacheShader( "waypoint_carepack_napalm" );
	precacheShader( "waypoint_carepack_ac130" );
	precacheShader( "waypoint_carepack_nuke" );
	precacheShader( "waypoint_carepack_havock" );

	// hardpoint shaders
	precacheShader( "compass_objpoint_satallite" );
	precacheShader( "compass_objpoint_counteruav" );
	precacheShader( "hud_icon_minigun" );
	precacheShader( "hud_stealth" );
	precacheShader( "hud_nuke" );
	precacheShader( "hud_ac130" );
	precacheShader( "death_napalm" );
	precacheShader( "compass_objpoint_littlebird" );
	precacheShader( "compass_objpoint_helicopter" );	
	precacheShader( "compass_objpoint_airstrike" );
	precacheShader( "compass_objpoint_carepackage" );
	precacheShader( "compass_objpoint_harrier" );
	precacheShader( "compass_objpoint_havock" );
	
	precacheShader( "counter_radar_grain" );
	
	makeDvarServerInfo( "ui_uav_allies", 0 );
	makeDvarServerInfo( "ui_uav_axis", 0 );
	setDvar( "ui_uav_allies", 0 );
	setDvar( "ui_uav_axis", 0 );
	setDvar( "ui_uav_client", 0 );
	
	setDvar( "ui_jammeduav_allies", 0 );
	setDvar( "ui_jammeduav_axis", 0 );

	//-------- Hardpoint Limiter by Team ------------------

	game["allies_hardpointcount"] = [];
	game["axis_hardpointcount"] = [];
		
	game["allies_hardpointcount"]["uav"] = 0;
	game["axis_hardpointcount"]["uav"] = 0;

	game["allies_hardpointcount"]["counteruav"] = 0;
	game["axis_hardpointcount"]["counteruav"] = 0;

	game["allies_hardpointcount"]["carepackage"] = 0;
	game["axis_hardpointcount"]["carepackage"] = 0;

	game["allies_hardpointcount"]["airstrike"] = 0;
	game["axis_hardpointcount"]["airstrike"] = 0;

	game["allies_hardpointcount"]["chopper"] = 0;
	game["axis_hardpointcount"]["chopper"] = 0;

	game["allies_hardpointcount"]["sentrygun"] = 0;
	game["axis_hardpointcount"]["sentrygun"] = 0;

	game["allies_hardpointcount"]["littlebird"] = 0;
	game["axis_hardpointcount"]["littlebird"] = 0;

	game["allies_hardpointcount"]["harrier"] = 0;
	game["axis_hardpointcount"]["harrier"] = 0;
	
	game["allies_hardpointcount"]["stealth"] = 0;
	game["axis_hardpointcount"]["stealth"] = 0;
	
	game["allies_hardpointcount"]["ac130"] = 0;
	game["axis_hardpointcount"]["ac130"] = 0;
	
	game["allies_hardpointcount"]["nuke"] = 0;
	game["axis_hardpointcount"]["nuke"] = 0;
	
	game["allies_hardpointcount"]["napalm"] = 0;
	game["axis_hardpointcount"]["napalm"] = 0;
	
    game["allies_hardpointcount"]["havock"] = 0;
	game["axis_hardpointcount"]["havock"] = 0;
	
	//-----------------------------------------------------
	
	level.hardpointItems = [];
	priority = 0;
	level.hardpointItems["radar_mp"] = priority;
	priority++;
	level.hardpointItems["counteruav_mp"] = priority;
	priority++;
	level.hardpointItems["carepackage_mp"] = priority;
	priority++;
	level.hardpointItems["sentrygun_mp"] = priority;
	priority++;
	level.hardpointItems["airstrike_mp"] = priority;
	priority++;
	level.hardpointItems["napalm_mp"] = priority;
	priority++;
	level.hardpointItems["littlebird_mp"] = priority;
	priority++;
	level.hardpointItems["stealth_mp"] = priority;
	priority++;
	level.hardpointItems["helicopter_mp"] = priority;
	priority++;
	level.hardpointItems["harrier_mp"] = priority;
	priority++;
	level.hardpointItems["nuke_mp"] = priority;
	priority++;
	level.hardpointItems["ac130_mp"] = priority;
	priority++;
	level.hardpointItems["havock_mp"] = priority;
	priority++;

	level.hardpointHints["radar_mp"] = &"MP_EARNED_RADAR";
	level.hardpointHints["airstrike_mp"] = &"MP_EARNED_AIRSTRIKE";
	level.hardpointHints["helicopter_mp"] = &"MP_EARNED_HELICOPTER";
	level.hardpointHints["sentrygun_mp"] = &"HARDPOINTS_EARNED_SENTRYGUN";
	level.hardpointHints["littlebird_mp"] = &"HARDPOINTS_EARNED_LITTLEBIRD";
	level.hardpointHints["counteruav_mp"] = &"HARDPOINTS_EARNED_COUNTERUAV";
	level.hardpointHints["carepackage_mp"] = &"HARDPOINTS_EARNED_CAREPACKAGE";
	level.hardpointHints["harrier_mp"] = &"HARDPOINTS_EARNED_HARRIER";
	level.hardpointHints["stealth_mp"] = &"HARDPOINTS_EARNED_STEALTH";
	level.hardpointHints["napalm_mp"] = &"HARDPOINTS_EARNED_NAPALM";
	level.hardpointHints["ac130_mp"] = &"HARDPOINTS_EARNED_ac130";
	level.hardpointHints["nuke_mp"] = &"HARDPOINTS_EARNED_nuke";
	level.hardpointHints["havock_mp"] = &"HARDPOINTS_EARNED_havock";

	level.hardpointHints["radar_mp_not_available"] = &"MP_RADAR_NOT_AVAILABLE";
	level.hardpointHints["airstrike_mp_not_available"] = &"MP_AIRSTRIKE_NOT_AVAILABLE";
	level.hardpointHints["helicopter_mp_not_available"] = &"MP_HELICOPTER_NOT_AVAILABLE";
	level.hardpointHints["sentrygun_mp_not_available"] = &"HARDPOINTS_SENTRYGUN_NOT_AVAILABLE";
	level.hardpointHints["littlebird_mp_not_available"] = &"HARDPOINTS_LITTLEBIRD_NOT_AVAILABLE";
	level.hardpointHints["counteruav_mp_not_available"] = &"HARDPOINTS_COUNTERUAV_NOT_AVAILABLE";
	level.hardpointHints["carepackage_mp_not_available"] = &"HARDPOINTS_CAREPACKAGE_NOT_AVAILABLE";
	level.hardpointHints["harrier_mp_not_available"] = &"HARDPOINTS_HARRIER_NOT_AVAILABLE";
	level.hardpointHints["stealth_mp_not_available"] = &"HARDPOINTS_STEALTH_NOT_AVAILABLE";
	level.hardpointHints["napalm_mp_not_available"] = &"HARDPOINTS_NAPALM_NOT_AVAILABLE";
	level.hardpointHints["ac130_mp_not_available"] = &"HARDPOINTS_ac130_NOT_AVAILABLE";
	level.hardpointHints["nuke_mp_not_available"] = &"HARDPOINTS_nuke_NOT_AVAILABLE";
	level.hardpointHints["havock_mp_not_available"] = &"HARDPOINTS_havock_NOT_AVAILABLE";
	
	//--- killsteak sounds ---
	level.hardpointInforms["radar_mp"] = "mp_killstreak_radar";
	level.hardpointInforms["airstrike_mp"] = "mp_killstreak_jet";
	level.hardpointInforms["napalm_mp"] = "mp_killstreak_jet";
	level.hardpointInforms["helicopter_mp"] = "mp_killstreak_heli";
	level.hardpointInforms["sentrygun_mp"] = "mp_killstreak_sentrygun";
	level.hardpointInforms["littlebird_mp"] = "mp_killstreak_littlebird";
	level.hardpointInforms["counteruav_mp"] = "mp_killstreak_counteruav";
	level.hardpointInforms["carepackage_mp"] = "mp_killstreak_littlebird";
	level.hardpointInforms["harrier_mp"] = "mp_killstreak_harrier";
	level.hardpointInforms["stealth_mp"] = "mp_killstreak_stealth";
	level.hardpointInforms["ac130_mp"] = "mp_killstreak_ac130";
	level.hardpointInforms["nuke_mp"] = "mp_killstreak_nuke";
	level.hardpointInforms["havock_mp"] = "mp_killstreak_havock";

	maps\mp\gametypes\_rank::registerScoreInfo( "hardpoint", 10 );
	
	precacheString( level.hardpointHints["radar_mp"] );	
	precacheString( level.hardpointHints["airstrike_mp"] );	
	precacheString( level.hardpointHints["helicopter_mp"] );	
	precacheString( level.hardpointHints["sentrygun_mp"] );
	precacheString( level.hardpointHints["littlebird_mp"] );
	precacheString( level.hardpointHints["counteruav_mp"] );
	precacheString( level.hardpointHints["carepackage_mp"] );
	precacheString( level.hardpointHints["harrier_mp"] );
	precacheString( level.hardpointHints["stealth_mp"] );
	precacheString( level.hardpointHints["napalm_mp"] );
	precacheString( level.hardpointHints["nuke_mp"] );
	precacheString( level.hardpointHints["ac130_mp"] );
	precacheString( level.hardpointHints["havock_mp"] );
	
	precacheString( level.hardpointHints["radar_mp_not_available"] );	
	precacheString( level.hardpointHints["airstrike_mp_not_available"] );	
	precacheString( level.hardpointHints["helicopter_mp_not_available"] );	
	precacheString( level.hardpointHints["sentrygun_mp_not_available"] );
	precacheString( level.hardpointHints["littlebird_mp_not_available"] );
	precacheString( level.hardpointHints["counteruav_mp_not_available"] );
	precacheString( level.hardpointHints["carepackage_mp_not_available"] );
	precacheString( level.hardpointHints["harrier_mp_not_available"] );
	precacheString( level.hardpointHints["stealth_mp_not_available"] );
	precacheString( level.hardpointHints["napalm_mp_not_available"] );
	precacheString( level.hardpointHints["nuke_mp_not_available"] );
	precacheString( level.hardpointHints["ac130_mp_not_available"] );
	precacheString( level.hardpointHints["havock_mp_not_available"] );
	

	precacheString( &"MP_KILLSTREAK_N" );
	precacheString( &"HARDPOINTS_CAREPACKAGE_DEPLOYED" );
	precacheString( &"HARDPOINTS_HARRIER_DEPLOYED" );	

	precacheLocationSelector( "map_artillery_selector" );

	level.airstrikefx = loadfx ("explosions/clusterbomb");
	level.mortareffect = loadfx ("explosions/artilleryExp_dirt_brown");
	level.bombstrike = loadfx ("explosions/wall_explosion_pm_a");
	
	level.fx_airstrike_afterburner = loadfx ("fire/jet_afterburner");
	level.fx_airstrike_contrail = loadfx ("smoke/jet_contrail");
	level.fx_bomb_contrail = loadfx ("smoke/smoke_geotrail_javelin");
	
	level.napalmfx = loadfx ("extreme/napalm");
	
	
	level.bodyfire = loadfx("misc/body_fire_oneshot");
	
	level.fx_airstrike_explosion = loadfx( "explosions/tanker_explosion" );
	
	level.fx_heli_dust = loadfx ("treadfx/heli_dust_default");
	level.fx_heli_water = loadfx ("treadfx/heli_water");

	game["dialog"]["uav_online"] = "ouruavonline";
	game["dialog"]["uav_offline"] = "";
	game["dialog"]["enemy_uav_online"] = "enemyuavair";
	game["dialog"]["enemy_uav_offline"] = "";
	game["dialog"]["airstrike_inbound"] = "friendlyair";
	game["dialog"]["enemy_airstrike_inbound"] = "enemyair";
	game["dialog"]["helicopter_inbound"] = "friendlyheli";
	game["dialog"]["enemy_helicopter_inbound"] = "enemyheli";

	game["dialog"]["radar_mp"] = "uavrecon";
	game["dialog"]["airstrike_mp"] = "airstrike";
	game["dialog"]["helicopter_mp"] = "helisupport";
	
	game["dialog"]["nuke_friendly"] = "nuke_friendly";
	game["dialog"]["nuke_enemy"] = "nuke_enemy";
	game["dialog"]["nuke_mp"] = "nuke_ready";
	
	game["dialog"]["ac130_friendly"] = "ac130_friendly";
	game["dialog"]["ac130_enemy"] = "ac130_enemy";
	game["dialog"]["ac130_mp"] = "ac130_ready";
	
	// Little Bird
	game["dialog"]["littlebird_inbound"] = "friendly_littlebird";
	game["dialog"]["enemy_littlebird_inbound"] = "enemy_littlebird";
	game["dialog"]["littlebird_mp"] = "ready_littlebird";
	
	// Sentry Gun
	game["dialog"]["sentrygun_deployed"] = "friendly_sentrygun";
	game["dialog"]["enemy_sentrygun_deployed"] = "enemy_sentrygun";
	game["dialog"]["sentrygun_mp"] = "ready_sentrygun";
	
	// Carepackage
	game["dialog"]["carepackage_deployed"] = "friendly_carepackage";
	game["dialog"]["enemy_carepackage_deployed"] = "enemy_carepackage";
	game["dialog"]["carepackage_mp"] = "ready_carepackage";
	
	// Counter-UAV
	game["dialog"]["counteruav_deployed"] = "friendly_counteruav";
	game["dialog"]["enemy_counteruav_deployed"] = "enemy_counteruav";
	game["dialog"]["counteruav_mp"] = "ready_counteruav";
	
	// Harrier
	game["dialog"]["harrier_inbound"] = "friendly_harrier";
	game["dialog"]["enemy_harrier_inbound"] = "enemy_harrier";
	game["dialog"]["harrier_mp"] = "ready_harrier";
	
	// Havock
	game["dialog"]["havock_inbound"] = "friendly_havock";
	game["dialog"]["enemy_havock_inbound"] = "enemy_havock";
	game["dialog"]["havock_mp"] = "ready_havock";
	
	game["dialog"]["stealth_mp"] = "airstrike";
	
	game["dialog"]["napalm_mp"] = "airstrike";



	// time interval between usage of helicopter hardpoint
	if ( getdvar( "scr_heli_hardpoint_interval" ) != "" )
		level.helicopterInterval = getdvarfloat( "scr_heli_hardpoint_interval" );
	else
	{
		setdvar( "scr_heli_hardpoint_interval" , 180 );
		level.helicopterInterval = 180; // time between allowed uses of helicopter
	}
	
	// airstrike danger area is the circle of radius artilleryDangerMaxRadius 
	// stretched by a factor of artilleryDangerOvalScale in the direction of the incoming airstrike,
	// moved by artilleryDangerForwardPush * artilleryDangerMaxRadius in the same direction.
	// use scr_airstrikedebug to visualize.
	
	level.artilleryDangerMaxRadius = 450;
	level.artilleryDangerMinRadius = 300;
	level.artilleryDangerForwardPush = 1.5;
	level.artilleryDangerOvalScale = 6.0;
	
	//for counterUAv purposes
	level.counterUAVinUse = [];
	level.counterUAVinUse["allies"] = undefined;
	level.counterUAVinUse["axis"] = undefined;
	level.PlayercounterUAVinUse = undefined;
	
	level.artilleryMapRange = level.artilleryDangerMinRadius * .3 + level.artilleryDangerMaxRadius * .7;
	
	level.artilleryDangerMaxRadiusSq = level.artilleryDangerMaxRadius * level.artilleryDangerMaxRadius;
	
	level.artilleryDangerCenters = [];
	
	level.radarViewTime = level.uav_lifespan; // time radar remains active

	level.numHardpointReservedObjectives = 0;

	thread maps\mp\_helicopter::init();
	thread maps\mp\_harrier::init();
	thread demon\_ac130::init();
	thread demon\_nuke::init();
	thread maps\mp\_havock::init();
}

giveHardpointItemForStreak()
{
	streak = undefined;
	if( self.specialty[1] == "specialty_hardline" )
		streak = (self.cur_kill_streak+1);
	else
		streak = self.cur_kill_streak;
	
	if( self.pers["team"] == "allies" )
		team = "allies";
	else
		team = "axis";
	
	if( level.limit_hardpoint_byTeam )
	{
		if( streak == level.uav_num && game[ team + "_hardpointcount"]["uav"] < game["hardpoint_uav_limit"] )
		{
			self giveHardpoint( "radar_mp", streak );
			game[ team + "_hardpointcount"]["uav"]++;
		}
		else if( streak == level.counteruav_num && game[ team + "_hardpointcount"]["counteruav"] < game["hardpoint_counteruav_limit"] )
		{
			self giveHardpoint( "counteruav_mp", streak );
			game[ team + "_hardpointcount"]["counteruav"]++;
		}
		else if( streak == level.airstrike_num && game[ team + "_hardpointcount"]["airstrike"] < game["hardpoint_airstrike_limit"] )
		{
			self giveHardpoint( "airstrike_mp", streak );
			game[ team + "_hardpointcount"]["airstrike"]++;
		}
		else if( streak == level.carepackage_num && game[ team + "_hardpointcount"]["carepackage"] < game["hardpoint_carepackage_limit"] )
		{
			self giveHardpoint( "carepackage_mp", streak );
			game[ team + "_hardpointcount"]["carepackage"]++;
		}
		else if( streak == level.sentrygun_num && game[ team + "_hardpointcount"]["sentrygun"] < game["hardpoint_sentrygun_limit"] )
		{
			self giveHardpoint( "sentrygun_mp", streak );
			game[ team + "_hardpointcount"]["sentrygun"]++;
			self.sentryTurret_RespawnTimes = 0;
		}
		else if( streak == level.napalm_num && game[ team + "_hardpointcount"]["napalm"] < game["hardpoint_napalm_limit"] )
		{
			self giveHardpoint( "napalm_mp", streak );
			game[ team + "_hardpointcount"]["napalm"]++;
		}
		else if( streak == level.littlebird_num && game[ team + "_hardpointcount"]["littlebird"] < game["hardpoint_littlebird_limit"] )
		{
			self giveHardpoint( "littlebird_mp", streak );
			game[ team + "_hardpointcount"]["littlebird"]++;
		}
		else if( streak == level.stealth_num && game[ team + "_hardpointcount"]["stealth"] < game["hardpoint_stealth_limit"] )
		{
			self giveHardpoint( "stealth_mp", streak );
			game[ team + "_hardpointcount"]["stealth"]++;
		}
		else if( streak == level.chopper_num && game[ team + "_hardpointcount"]["chopper"] < game["hardpoint_chopper_limit"] )
		{
			self giveHardpoint( "helicopter_mp", streak );
			game[ team + "_hardpointcount"]["chopper"]++;
		}
		else if( streak == level.harrier_num && game[ team + "_hardpointcount"]["harrier"] < game["hardpoint_harrier_limit"] )
		{
			self giveHardpoint( "harrier_mp", streak );
			game[ team + "_hardpointcount"]["harrier"]++;
		}
		else if( streak == level.nuke_num && game[ team + "_hardpointcount"]["nuke"] < game["hardpoint_nuke_limit"] )
		{
			self giveHardpoint( "nuke_mp", streak );
			game[ team + "_hardpointcount"]["nuke"]++;
		}
		else if( streak == level.ac130_num && game[ team + "_hardpointcount"]["ac130"] < game["hardpoint_ac130_limit"] )
		{
			self giveHardpoint( "ac130_mp", streak );
			game[ team + "_hardpointcount"]["ac130"]++;
		}
		else if( streak == level.havock_num && game[ team + "_hardpointcount"]["havock"] < game["hardpoint_havock_limit"] )
		{
			self giveHardpoint( "havock_mp", streak );
			game[ team + "_hardpointcount"]["havock"]++;
		}
		else if( streak >= (level.harrier_num+4) )
		{
			if( (streak % 5) == 0 )
				self streakNotify( streak );
		}
	}
	else if( level.limit_hardpoint_byPlayer )
	{
		if( streak == level.uav_num && self.hardpointcount["uav"] < game["hardpoint_uav_limit"] )
		{
			self giveHardpoint( "radar_mp", streak );
			self.hardpointcount["uav"]++;
		}
		else if( streak == level.counteruav_num && self.hardpointcount["counteruav"] < game["hardpoint_counteruav_limit"] )
		{
			self giveHardpoint( "counteruav_mp", streak );
			self.hardpointcount["counteruav"]++;
		}
		else if( streak == level.airstrike_num && self.hardpointcount["airstrike"] < game["hardpoint_airstrike_limit"] )
		{
			self giveHardpoint( "airstrike_mp", streak );
			self.hardpointcount["airstrike"]++;
		}
		else if( streak == level.carepackage_num && self.hardpointcount["carepackage"] < game["hardpoint_carepackage_limit"] )
		{
			self giveHardpoint( "carepackage_mp", streak );
			self.hardpointcount["carepackage"]++;
		}
		else if( streak == level.sentrygun_num && self.hardpointcount["sentrygun"] < game["hardpoint_sentrygun_limit"] )
		{
			self giveHardpoint( "sentrygun_mp", streak );
			self.hardpointcount["sentrygun"]++;
			self.sentryTurret_RespawnTimes = 0;
		}
		else if( streak == level.napalm_num && self.hardpointcount["napalm"] < game["hardpoint_napalm_limit"] )
		{
			self giveHardpoint( "napalm_mp", streak );
			self.hardpointcount["napalm"]++;
		}
		else if( streak == level.stealth_num && game[ team + "_hardpointcount"]["stealth"] < game["hardpoint_stealth_limit"] )
		{
			self giveHardpoint( "stealth_mp", streak );
			game[ team + "_hardpointcount"]["stealth"]++;
		}
		else if( streak == level.littlebird_num && self.hardpointcount["littlebird"] < game["hardpoint_littlebird_limit"] )
		{
			self giveHardpoint( "littlebird_mp", streak );
			self.hardpointcount["littlebird"]++;
		}
		else if( streak == level.chopper_num && self.hardpointcount["chopper"] < game["hardpoint_chopper_limit"] )
		{
				self giveHardpoint( "helicopter_mp", streak );
				self.hardpointcount["chopper"]++;
		}
		else if( streak == level.harrier_num && self.hardpointcount["harrier"] < game["hardpoint_harrier_limit"] )
		{
			self giveHardpoint( "harrier_mp", streak );
			self.hardpointcount["harrier"]++;
		}
		else if( streak == level.nuke_num && game[ team + "_hardpointcount"]["nuke"] < game["hardpoint_nuke_limit"] )
		{
			self giveHardpoint( "nuke_mp", streak );
			self.hardpointcount["nuke"]++;
		}
		else if( streak == level.ac130_num && game[ team + "_hardpointcount"]["ac130"] < game["hardpoint_ac130_limit"] )
		{
			self giveHardpoint( "ac130_mp", streak );
			self.hardpointcount["ac130"]++;
		}
		else if( streak == level.havock_num && game[ team + "_hardpointcount"]["havock"] < game["hardpoint_havock_limit"] )
		{
			self giveHardpoint( "havock_mp", streak );
			self.hardpointcount["havock"]++;
		}
		else if( streak >= (level.harrier_num+4) )
		{
			if( (streak % 5) == 0 )
				self streakNotify( streak );
		}
	}
	else
	{
		if( streak == level.uav_num )
		{
			self giveHardpoint( "radar_mp", streak );
		}
		else if( streak == level.counteruav_num )
		{
			self giveHardpoint( "counteruav_mp", streak );
		}
		else if( streak == level.airstrike_num )
		{
			self giveHardpoint( "airstrike_mp", streak );
		}
		else if( streak == level.carepackage_num )
		{
			self giveHardpoint( "carepackage_mp", streak );
		}
		else if( streak == level.sentrygun_num )
		{
			self giveHardpoint( "sentrygun_mp", streak );
			self.sentryTurret_RespawnTimes = 0;
		}
		else if( streak == level.napalm_num )
		{
			self giveHardpoint( "napalm_mp", streak );
		}
		else if( streak == level.littlebird_num )
		{
			self giveHardpoint( "littlebird_mp", streak );
		}
		else if( streak == level.chopper_num )
		{
			self giveHardpoint( "helicopter_mp", streak );
		}
		else if( streak == level.stealth_num  )
		{
			self giveHardpoint( "stealth_mp", streak );
		}
		else if( streak == level.harrier_num )
		{
			self giveHardpoint( "harrier_mp", streak );
		}
		else if( streak == level.nuke_num && game[ team + "_hardpointcount"]["nuke"] < game["hardpoint_nuke_limit"] )
		{
			self giveHardpoint( "nuke_mp", streak );
		}
		else if( streak == level.ac130_num && game[ team + "_hardpointcount"]["ac130"] < game["hardpoint_ac130_limit"] )
		{
			self giveHardpoint( "ac130_mp", streak );
		}
		else if( streak == level.havock_num )
		{
			self giveHardpoint( "havock_mp", streak );
		}
		else if( streak >= (level.harrier_num+4) )
		{
			if( (streak % 5) == 0 )
				self streakNotify( streak );
		}	
	}

}

setPlayerDefaults()
{
	self.hardpointcount = [];
	self.hardpointcount["uav"] = 0;
	self.hardpointcount["airstrike"] = 0;
	self.hardpointcount["chopper"] = 0;
	self.hardpointcount["sentrygun"] = 0;
	self.hardpointcount["littlebird"] = 0;
	self.hardpointcount["counteruav"] = 0;
	self.hardpointcount["carepackage"] = 0;
	self.hardpointcount["harrier"] = 0;
	self.hardpointcount["stealth"] = 0;
	self.hardpointcount["napalm"] = 0;
	self.hardpointcount["nuke"] = 0;
	self.hardpointcount["ac130"] = 0;
	self.hardpointcount["havock"] = 0;
}

distance2d(a,b)
{
	return distance((a[0],a[1],0), (b[0],b[1],0));
}

teamHasRadar(team)
{
	return getTeamRadar(team);
}

doAirstrike( isStealth, origin, owner, team )
{
	num = 17 + randomint(3);
	
	level.airstrikeInProgress = true;
	trace = bullettrace(origin, origin + (0,0,-10000), false, undefined);
	targetpos = trace["position"];
	
	yaw = getBestPlaneDirection( targetpos );
	
	if ( level.teambased )
	{
		players = level.players;
		if ( !level.hardcoreMode )
		{
			for(i = 0; i < players.size; i++)
			{
				if(isalive(players[i]) && (isdefined(players[i].pers["team"])) && (players[i].pers["team"] == team)) {
					if ( pointIsInAirstrikeArea( players[i].origin, targetpos, yaw ) )
						players[i] iprintlnbold(&"MP_WAR_AIRSTRIKE_INBOUND_NEAR_YOUR_POSITION");
				}
			}
		}
		
		maps\mp\gametypes\_globallogic::leaderDialog( "airstrike_inbound", team );
		for ( i = 0; i < level.players.size; i++ )
		{
			player = level.players[i];
			playerteam = player.pers["team"];
			if ( isdefined( playerteam ) )
			{
				if ( playerteam == team )
					player iprintln( &"MP_WAR_AIRSTRIKE_INBOUND", owner );
			}
		}
	}
	else
	{
		owner maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "airstrike_inbound" );

		if ( !level.hardcoreMode )
		{
			if ( pointIsInAirstrikeArea( owner.origin, targetpos, yaw ) )
				owner iprintlnbold(&"MP_WAR_AIRSTRIKE_INBOUND_NEAR_YOUR_POSITION");
		}
	}
	
	wait 2;

	if ( !isDefined( owner ) )
	{
		level.airstrikeInProgress = undefined;
		return;
	}
	
	owner notify ( "begin_airstrike" );
	owner.isUsingAirstrike = true;
	
	dangerCenter = spawnstruct();
	dangerCenter.origin = targetpos;
	dangerCenter.forward = anglesToForward( (0,yaw,0) );
	level.artilleryDangerCenters[ level.artilleryDangerCenters.size ] = dangerCenter;
	/# level thread debugArtilleryDangerCenters(); #/
	
	callStrike( isStealth, owner, targetpos, yaw );
	
	wait 8.5;
	
	found = false;
	newarray = [];
	for ( i = 0; i < level.artilleryDangerCenters.size; i++ )
	{
		if ( !found && level.artilleryDangerCenters[i].origin == targetpos )
		{
			found = true;
			continue;
		}
		
		newarray[ newarray.size ] = level.artilleryDangerCenters[i];
	}
	assert( found );
	assert( newarray.size == level.artilleryDangerCenters.size - 1 );
	level.artilleryDangerCenters = newarray;

	level.airstrikeInProgress = undefined;
}

/#
debugArtilleryDangerCenters()
{
	level notify("debugArtilleryDangerCenters_thread");
	level endon("debugArtilleryDangerCenters_thread");
	
	if ( getdvar("scr_airstrikedebug") != "1" && getdvar("scr_spawnpointdebug") == "0" )
	{
		return;
	}
	
	while( level.artilleryDangerCenters.size > 0 )
	{
		for ( i = 0; i < level.artilleryDangerCenters.size; i++ )
		{
			origin = level.artilleryDangerCenters[i].origin;
			forward = level.artilleryDangerCenters[i].forward;
			
			origin += forward * level.artilleryDangerForwardPush * level.artilleryDangerMaxRadius;
			
			previnnerpos = (0,0,0);
			prevouterpos = (0,0,0);
			for ( j = 0; j <= 40; j++ )
			{
				frac = (j * 1.0) / 40;
				angle = frac * 360;
				dir = anglesToForward((0,angle,0));
				forwardPart = vectordot( dir, forward ) * forward;
				perpendicularPart = dir - forwardPart;
				pos = forwardPart * level.artilleryDangerOvalScale + perpendicularPart;
				innerpos = pos * level.artilleryDangerMinRadius;
				innerpos += origin;
				outerpos = pos * level.artilleryDangerMaxRadius;
				outerpos += origin;
				
				if ( j > 0 )
				{
					line( innerpos, previnnerpos, (1, 0, 0) );
					line( outerpos, prevouterpos, (1,.5,.5) );
				}
				
				previnnerpos = innerpos;
				prevouterpos = outerpos;
			}
		}
		wait .05;
	}
}
#/

getAirstrikeDanger( point )
{
	danger = 0;
	for ( i = 0; i < level.artilleryDangerCenters.size; i++ )
	{
		origin = level.artilleryDangerCenters[i].origin;
		forward = level.artilleryDangerCenters[i].forward;
		
		danger += getSingleAirstrikeDanger( point, origin, forward );
	}
	return danger;
}

getSingleAirstrikeDanger( point, origin, forward )
{
	center = origin + level.artilleryDangerForwardPush * level.artilleryDangerMaxRadius * forward;
	
	diff = point - center;
	diff = (diff[0], diff[1], 0);
	
	forwardPart = vectorDot( diff, forward ) * forward;
	perpendicularPart = diff - forwardPart;
	
	circlePos = perpendicularPart + forwardPart / level.artilleryDangerOvalScale;
	
	distsq = lengthSquared( circlePos );
	
	if ( distsq > level.artilleryDangerMaxRadius * level.artilleryDangerMaxRadius )
		return 0;
	
	if ( distsq < level.artilleryDangerMinRadius * level.artilleryDangerMinRadius )
		return 1;
	
	dist = sqrt( distsq );
	distFrac = (dist - level.artilleryDangerMinRadius) / (level.artilleryDangerMaxRadius - level.artilleryDangerMinRadius);
	
	assertEx( distFrac >= 0 && distFrac <= 1, distFrac );
	
	return 1 - distFrac;
}

pointIsInAirstrikeArea( point, targetpos, yaw )
{
	return distance2d( point, targetpos ) <= level.artilleryDangerMaxRadius * 1.25;
	// TODO
	//return getSingleAirstrikeDanger( point, targetpos, yaw ) > 0;
}

losRadiusDamage(isNapalm, pos, radius, max, min, owner, eInflictor)
{
	if (!isdefined(pos))
	return;

	ents = maps\mp\gametypes\_weapons::getDamageableEnts(pos, radius, true);

	for (i = 0; i < ents.size; i++)
	{
		if (ents[i].entity == self)
			continue;
		
		dist = distance(pos, ents[i].damageCenter);
		
		if ( ents[i].isPlayer )
		{
			// check if there is a path to this entity 130 units above his feet. if not, they're probably indoors
			indoors = !maps\mp\gametypes\_weapons::weaponDamageTracePassed( ents[i].entity.origin, ents[i].entity.origin + (0,0,130), 0, undefined );
			if ( !indoors )
			{
				indoors = !maps\mp\gametypes\_weapons::weaponDamageTracePassed( ents[i].entity.origin + (0,0,130), pos + (0,0,130 - 16), 0, undefined );
				if ( indoors )
				{
					// give them a distance advantage for being indoors.
					dist *= 4;
					if ( dist > radius )
						continue;
				}
			}
		}

		ents[i].damage = int(max + (min-max)*dist/radius);
		ents[i].pos = pos;
		ents[i].damageOwner = owner;
		ents[i].eInflictor = eInflictor;
		level.airStrikeDamagedEnts[level.airStrikeDamagedEntsCount] = ents[i];
		level.airStrikeDamagedEntsCount++;
	}
	if (isNapalm)
	thread doNapalm();
	else
	thread airstrikeDamageEntsThread();
}

airstrikeDamageEntsThread()
{
	self notify ( "airstrikeDamageEntsThread" );
	self endon ( "airstrikeDamageEntsThread" );

	for( ; level.airstrikeDamagedEntsIndex < level.airstrikeDamagedEntsCount; level.airstrikeDamagedEntsIndex++ )
	{
		if ( !isDefined( level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] ) )
			continue;

		ent = level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex];
		
		if ( !isDefined( ent.entity ) )
			continue; 
			
		if ( !ent.isPlayer || isAlive( ent.entity ) )
		{
			ent maps\mp\gametypes\_weapons::damageEnt(
				ent.eInflictor, // eInflictor = the entity that causes the damage (e.g. a claymore)
				ent.damageOwner, // eAttacker = the player that is attacking
				ent.damage, // iDamage = the amount of damage to do
				"MOD_PROJECTILE_SPLASH", // sMeansOfDeath = string specifying the method of death (e.g. "MOD_PROJECTILE_SPLASH")
				"airstrike_mp", // sWeapon = string specifying the weapon used (e.g. "claymore_mp")
				ent.pos, // damagepos = the position damage is coming from
				vectornormalize(ent.damageCenter - ent.pos) // damagedir = the direction damage is moving in
			);			

			level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] = undefined;
			
			if ( ent.isPlayer )
				wait ( 0.05 );
		}
		else
		{
			level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] = undefined;
		}
	}
}

radiusArtilleryShellshock(pos, radius, maxduration,minduration)
{
	players = level.players;
	for (i = 0; i < players.size; i++)
	{
		if (!isalive(players[i]))
			continue;
		
		playerpos = players[i].origin + (0,0,32);
		dist = distance(pos, playerpos);
		if (dist < radius) {
			duration = int(maxduration + (minduration-maxduration)*dist/radius);
			
			players[i] thread artilleryShellshock("default", duration);
		}
	}
}

artilleryShellshock(type, duration)
{
	if (isdefined( self.beingArtilleryShellshocked ) && self.beingArtilleryShellshocked)
		return;
	self.beingArtilleryShellshocked = true;
	
	self shellshock(type, duration);
	wait(duration + 1);
	
	self.beingArtilleryShellshocked = false;
}


/#
airstrikeLine( start, end, color, duration )
{
	frames = duration * 20;
	for ( i = 0; i < frames; i++ )
	{
		line(start,end,color);
		wait .05;
	}
}


traceBomb()
{
	self endon("death");
	prevpos = self.origin;
	while(1)
	{
		thread airstrikeLine( prevpos, self.origin, (.5,1,0), 20 );
		prevpos = self.origin;
		wait .2;
	}
}
#/

doPlaneStrike( isStealth, owner, requiredDeathCount, bombsite, startPoint, endPoint, bombTime, flyTime, direction )
{
	// plane spawning randomness = up to 125 units, biased towards 0
	// radius of bomb damage is 512

	if ( !isDefined( owner ) ) 
		return;
	
	startPathRandomness = 100;
	endPathRandomness = 150;
	
	pathStart = startPoint + ( (randomfloat(2) - 1)*startPathRandomness, (randomfloat(2) - 1)*startPathRandomness, 0 );
	pathEnd   = endPoint   + ( (randomfloat(2) - 1)*endPathRandomness  , (randomfloat(2) - 1)*endPathRandomness  , 0 );
	
	// Spawn the planes
	plane = spawnplane( owner, "script_model", pathStart );
	if (isStealth==1)
		plane setModel( "jokers_stealth" );
	else
		plane setModel( "vehicle_mig29_desert" );
	plane.angles = direction;
	
	if (isStealth!=1)
	plane thread playPlaneFx();
	
	plane moveTo( pathEnd, flyTime, 0, 0 );
	
	/#
	if ( getdvar("scr_airstrikedebug") == "1" )
		thread airstrikeLine( pathStart, pathEnd, (1,1,1), 10 );
	#/
	
	thread callStrike_planeSound( plane, bombsite );
	
	if (isStealth==1)
		plane thread bombsetup(owner, bombTime - 0.5, requiredDeathCount);
	else
		thread callStrike_bombEffect( (isStealth==2), plane, bombTime - 1.0, owner, requiredDeathCount );
	
	// Delete the plane after its flyby
	wait flyTime;
	plane notify( "delete" );
	plane delete();
}


callStrike_bombEffect( isNapalm, plane, launchTime, owner, requiredDeathCount )
{
	wait ( launchTime );
	
	plane thread play_sound_in_space( "veh_mig29_sonic_boom" );
	
	bomb = spawnbomb( plane.origin, plane.angles );
	bomb moveGravity( vector_scale( anglestoforward( plane.angles ), 7000/1.5 ), 3.0 );
	
	bomb.ownerRequiredDeathCount = requiredDeathCount;
	
	/#
	if ( getdvar("scr_airstrikedebug") == "1" )
		 bomb thread traceBomb();
	#/
	
	wait ( 0.85 );
	bomb.killCamEnt = spawn( "script_model", bomb.origin + (0,0,200) );
	bomb.killCamEnt.angles = bomb.angles;
	bomb.killCamEnt thread deleteAfterTime( 10.0 );
	bomb.killCamEnt moveTo( bomb.killCamEnt.origin + vector_scale( anglestoforward( plane.angles ), 1000 ), 3.0 );
	wait ( 0.15 );

	newBomb = spawn( "script_model", bomb.origin );
 	newBomb setModel( "tag_origin" );
  	newBomb.origin = bomb.origin;
  	newBomb.angles = bomb.angles;

	bomb setModel( "tag_origin" );
	//plane moveTo( endPoint + ( (randomint( 300 ) - 150 ), (randomint( 300 ) - 150 ), 0 ), flyTime, 0, 0 );
	wait (0.05);
	
	bombOrigin = newBomb.origin;
	bombAngles = newBomb.angles;
	if (isNapalm) 
	{
		playfxontag( level.napalmfx, newBomb, "tag_origin" );
		playfxontag( level.fx_airstrike_explosion, newBomb, "tag_origin" );
	}
	else
	playfxontag( level.airstrikefx, newBomb, "tag_origin" );
	
	wait ( 0.5 );
	repeat = 12;
	minAngles = 5;
	maxAngles = 55;
	angleDiff = (maxAngles - minAngles) / repeat;
	
	for( i = 0; i < repeat; i++ )
	{
		traceDir = anglesToForward( bombAngles + (maxAngles-(angleDiff * i),randomInt( 10 )-5,0) );
		traceEnd = bombOrigin + vector_scale( traceDir, 10000 );
		trace = bulletTrace( bombOrigin, traceEnd, false, undefined );
		
		traceHit = trace["position"];
		
		/#
		if ( getdvar("scr_airstrikedebug") == "1" )
			thread airstrikeLine( bombOrigin, traceHit, (1,0,0), 20 );
		#/
		if (isNapalm)
		thread losRadiusDamage(isNapalm,  traceHit + (0,0,16), 768, 200, 30, owner, bomb );
		else
		thread losRadiusDamage(isNapalm,  traceHit + (0,0,16), 512, 200, 30, owner, bomb ); // targetpos, radius, maxdamage, mindamage, player causing damage, entity that player used to cause damage
	
		if ( i%3 == 0 )
		{
			if (isNapalm)
			thread playsoundinspace( "napalm_burst", traceHit );
			thread playsoundinspace( "artillery_impact", traceHit );
			playRumbleOnPosition( "artillery_rumble", traceHit );
			earthquake( 0.7, 0.75, traceHit, 1000 );
		}
		
		wait ( 0.05 );
	}
	wait ( 5.0 );
	newBomb delete();
	bomb delete();
	owner.isUsingAirstrike = undefined;
}

doNapalm()
{
	self notify ( "airstrikeDamageEntsThread" );
	self endon ( "airstrikeDamageEntsThread" );
	for( ; level.airstrikeDamagedEntsIndex < level.airstrikeDamagedEntsCount; level.airstrikeDamagedEntsIndex++ )
	{
		if ( !isDefined( level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] ) )
			continue;

		ent = level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex];
		
		if ( !isDefined( ent.entity ) )
			continue; 
			
		if ( !ent.isPlayer || isAlive( ent.entity ) )
		{
			if (ent.isPlayer)
			ent.entity thread napalmDamage(ent.damageOwner);

			level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] = undefined;
			
			if ( ent.isPlayer )
				wait ( 0.05 );
		}
		else
		{
			level.airstrikeDamagedEnts[level.airstrikeDamagedEntsIndex] = undefined;
		}
	}
}

napalmDamage(eAttacker)
{
	self endon("disconnect");
	self endon("death");
	

	// Respect friendly fire settings 0 (off) and 2 (reflect; it doesn't damage the attacker though)
	friendly = false;
	if(level.friendlyfire == 2)
		if(isPlayer(eAttacker) && eAttacker.pers["team"] == self.pers["team"]) friendly = true;	
	// burn them c/w damage
	if(isPlayer(self) && !friendly) self doTorch(true, eAttacker);
	
	// play flame on dead body & make sure they die!
	if(isPlayer(self))
	{
		//if(!friendly) playfx(level.ex_effect["bodygroundfire"], self.origin);
		self thread [[level.callbackPlayerDamage]](eAttacker, eAttacker, 1000, 1, "MOD_PROJECTILE", "airstrike_mp", undefined, (0,0,1), "none", 0);
	}
}

doTorch(special, eAttacker)
{
	self endon("disconnect");
	self endon("spawned");
	self endon("death");

			
	if(!isDefined(special)) special = false;
	if(!isDefined(eAttacker)) eAttacker = self;

	self thread doFire();

	for(i = 0; i < 10; i++)
	{
		if(isPlayer(self) && special) self thread [[level.callbackPlayerDamage]](eAttacker, eAttacker, randomInt(2) + 2, 1, "MOD_PROJECTILE", "airstrike_mp", undefined, (0,0,1), "none",0);
		wait 2;
	}

	if(special) return;

	if(isPlayer(self))
	{
		self suicide();
	}
}

doFire()
{
	self endon("disconnect");
	self endon("death");
	for(;;)
	{
		wait .2;
		if(isPlayer(self))
		{
			playfxontag(level.bodyfire, self, "j_elbow_le");
			playfxontag(level.bodyfire, self, "j_elbow_ri");
			playfxontag(level.bodyfire, self, "torso_stabilizer");
		}
	}
}

spawnbomb( origin, angles )
{
	bomb = spawn( "script_model", origin );
	bomb.angles = angles;
	bomb setModel( "projectile_cbu97_clusterbomb" );

	return bomb;
}

deleteAfterTime( time )
{
	self endon ( "death" );
	wait ( 10.0 );
	
	self delete();
}

drawLine( start, end, timeSlice )
{
	drawTime = int(timeSlice * 20);
	for( time = 0; time < drawTime; time++ )
	{
		line( start, end, (1,0,0),false, 1 );
		wait ( 0.05 );
	}
}

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

	
	playfxontag( level.fx_airstrike_afterburner, self, "tag_engine_right" );
	playfxontag( level.fx_airstrike_afterburner, self, "tag_engine_left" );
	playfxontag( level.fx_airstrike_contrail, self, "tag_right_wingtip" );
	playfxontag( level.fx_airstrike_contrail, self, "tag_left_wingtip" );
}

playBombFx()
{
	self endon ( "death" );
		wait 0.1; 
		playfxontag( level.fx_bomb_contrail, self, "tag_fx" );
}

getBestPlaneDirection( hitpos )
{
	if ( getdvarint("scr_airstrikebestangle") != 1 )
		return randomfloat( 360 );
	
	checkPitch = -25;
	
	numChecks = 15;
	
	startpos = hitpos + (0,0,64);
	
	bestangle = randomfloat( 360 );
	bestanglefrac = 0;
	
	fullTraceResults = [];
	
	for ( i = 0; i < numChecks; i++ )
	{
		yaw = ((i * 1.0 + randomfloat(1)) / numChecks) * 360.0;
		angle = (checkPitch, yaw + 180, 0);
		dir = anglesToForward( angle );
		
		endpos = startpos + dir * 1500;
		
		trace = bullettrace( startpos, endpos, false, undefined );
		
		/#
		if ( getdvar("scr_airstrikedebug") == "1" )
			thread airstrikeLine( startpos, trace["position"], (1,1,0), 20 );
		#/
		
		if ( trace["fraction"] > bestanglefrac )
		{
			bestanglefrac = trace["fraction"];
			bestangle = yaw;
			
			if ( trace["fraction"] >= 1 )
				fullTraceResults[ fullTraceResults.size ] = yaw;
		}
		
		if ( i % 3 == 0 )
			wait .05;
	}
	
	if ( fullTraceResults.size > 0 )
		return fullTraceResults[ randomint( fullTraceResults.size ) ];
	
	return bestangle;
}

callStrike( isStealth, owner, coord, yaw )
{	
	// Get starting and ending point for the plane
	direction = ( 0, yaw, 0 );
	if (isStealth==1)
	planeHalfDistance = 10000;
	else
	planeHalfDistance = 24000;
	planeBombExplodeDistance = 1500;
	planeFlyHeight = 850;
	planeFlySpeed = 7000;

	if ( isdefined( level.airstrikeHeightScale ) )
	{
		planeFlyHeight *= level.airstrikeHeightScale;
	}
	
	startPoint = coord + vector_scale( anglestoforward( direction ), -1 * planeHalfDistance );
	startPoint += ( 0, 0, planeFlyHeight );

	endPoint = coord + vector_scale( anglestoforward( direction ), planeHalfDistance );
	endPoint += ( 0, 0, planeFlyHeight );
	
	// Make the plane fly by
	d = length( startPoint - endPoint );
	if (isStealth==1)
	{
		apspeed = 30; // bombers
		flyTime = calcTime(startPoint, endPoint, apspeed);
		bombTime = calcTime(startPoint,coord-vector_scale( anglestoforward( direction ), 500), apspeed);;
	}
	else {
	flyTime = ( d / planeFlySpeed );
	
	// bomb explodes planeBombExplodeDistance after the plane passes the center
		d = abs( d/2 + planeBombExplodeDistance  );
		bombTime = ( d / planeFlySpeed );
	}
	
	assert( flyTime > bombTime );
	
	owner endon("disconnect");
	
	requiredDeathCount = owner.deathCount;
	
	level.airstrikeDamagedEnts = [];
	level.airStrikeDamagedEntsCount = 0;
	level.airStrikeDamagedEntsIndex = 0;
	if (isStealth==0) {
		level thread doPlaneStrike( false, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(500)), endPoint+(0,0,randomInt(500)), bombTime, flyTime, direction );
		wait randomfloatrange( 1.5, 2.5 );
		level thread doPlaneStrike( false, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction );
		wait randomfloatrange( 1.5, 2.5 );
		level thread doPlaneStrike( false, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction );
	} else {
		level thread doPlaneStrike( isStealth, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(500)), endPoint+(0,0,randomInt(500)), bombTime, flyTime, direction );
		/*wait randomfloatrange( 1.5, 2.5 );
		level thread doPlaneStrike( true, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction );
		wait randomfloatrange( 1.5, 2.5 );
		level thread doPlaneStrike( true, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction );
		wait randomfloatrange( 1.5, 2.5 );
		level thread doPlaneStrike( true, owner, requiredDeathCount, coord, startPoint+(0,0,randomInt(200)), endPoint+(0,0,randomInt(200)), bombTime, flyTime, direction );*/
	}
}

callStrike_bomb( bombTime, coord, repeat, owner )
{
	accuracyRadius = 512;
	
	for( i = 0; i < repeat; i++ )
	{
		randVec = ( 0, randomint( 360 ), 0 );
		bombPoint = coord + vector_scale( anglestoforward( randVec ), accuracyRadius );
		
		wait bombTime;
		
		thread playsoundinspace( "artillery_impact", bombPoint );
		radiusArtilleryShellshock( bombPoint, 512, 8, 4);
		losRadiusDamage( false, bombPoint + (0,0,16), 768, 300, 50, owner); // targetpos, radius, maxdamage, mindamage, player causing damage
	}
}

bombsetup(owner, launchTime, requiredDeathCount)
{
	owner endon("disconnect");
	
	self.ownerRequiredDeathCount = requiredDeathCount;
	
	wait launchTime;

	bombcount = 0;
	bombno = randomInt(6) + 10;

	while(bombcount < bombno)
	{
		self thread dropabomb(owner);
		bombcount++;
		wait 0.1;
	}
}

spawnsbomb( origin, angles )
{
	bomb = spawn( "script_model", origin );
	bomb.angles = angles;
	bomb setModel( "projectile_cbu97_clusterbomb" );

		bomb thread playBombFx(); //----------------------------)

	return bomb;
}

dropabomb(owner)
{
	if(!isdefined(self)) return;
	
	x = self.origin[0];
	y = self.origin[1];
	z = self.origin[2];

	startpoint = self.origin;
	forwardvector = anglestoforward(self.angles);
	endorigin = startpoint + vector_scale(forwardvector,360);


	// spawn the bomb and drop it
	bomb = spawnsbomb( self.origin, self.angles );
   bomb.ownerRequiredDeathCount = self.ownerRequiredDeathCount;
	// get the impact point
	//trace = bulletTrace(startpoint,(endorigin[0],endorigin[1],endorigin[2] - 2048), false, self);
	
	trace = bullettrace( bomb.origin, bomb.origin + anglestoForward( (45, bomb.angles[1], 0) ) * 5000, false, self);
	hit = trace["position"] + (0,0,50);
	bomb moveto(hit, 2, 2);
	bomb rotateTo( (45,bomb.angles[1], bomb.angles[2]), 2);
	
	/*endorigin = trace["position"];
	//	else return; // if no proper position then skip the bomb

	// bomb falltime
	falltime = calcTime(startpoint, endorigin, 20);
	//if(falltime < 0.5) return; // abort


	bomb moveto(endorigin + (0,0, - 100), falltime);

	// wait for it to hit
	wait falltime;*/
	
	wait ( 0.85 );
   bomb.killCamEnt = spawn( "script_model", bomb.origin + (0,0,200) );
   bomb.killCamEnt.angles = bomb.angles;
   bomb.killCamEnt thread deleteAfterTime( 10.0 );
   bomb.killCamEnt moveTo( bomb.killCamEnt.origin + vector_scale( anglestoforward( self.angles ), 1000 ), 3.0 );
   wait ( 0.15 );
   
   wait 1;
   
   /*  newBomb = spawn( "script_model", bomb.origin );
   newBomb setModel( "tag_origin" );
	 newBomb.origin = bomb.origin;
	 newBomb.angles = bomb.angles;*/

   bomb setModel( "tag_origin" );
   wait (0.05);


   bombOrigin = bomb.origin;
   bombAngles = bomb.angles;
   playfxontag( level.airstrikefx, bomb, "tag_origin" );

   wait ( 0.05 );
   repeat = 12; //BOMBLETS
   minAngles = 55;
   maxAngles = 100;
   angleDiff = (maxAngles - minAngles) / repeat;

   for( i = 0; i < repeat; i++ )
   {
	  traceDir = anglesToForward( bombAngles + (maxAngles-(angleDiff * i),randomInt( 10 )-5,0) );
	  traceEnd = bombOrigin + vector_scale( traceDir, 100 );
	  trace = bulletTrace( bombOrigin, traceEnd, false, undefined );

	  traceHit = trace["position"];

	  thread losRadiusDamage( false, traceHit + (0,0,16), 512, 200, 100, owner, bomb ); // targetpos, radius, maxdamage, mindamage, player causing damage, entity that player used to cause damage

	  if ( i%3 == 0 )
	  {
		 thread playsoundinspace( "artillery_impact", traceHit );
		 playRumbleOnPosition( "artillery_rumble", traceHit );
		 earthquake( 0.7, 0.75, traceHit, 1000 );
	  }

	  wait ( 0.05 );
   }
   wait ( 5.0 );
   //newBomb delete();
   bomb delete();
   
   /*

	// do the damage
	thread radiusArtilleryShellshock( endorigin, 512, 8, 4);
	thread losRadiusDamage( endorigin + (0,0,48), 600, 200, 90, owner, bomb );
	//losRadiusDamage( endorigin + (0,0,48), 800, 300, 100, owner); 
	earthquake( 0.7, 0.75, endorigin, 1000 );
	playfx(level.fx_airstrike_explosion, endorigin);


	// play the explosion sound
	bombsfx[0] = "artillery_impact";
	bombsfx[1] = "artillery_impact";
	bombsfx[2] = "artillery_impact";
	bombsfx[3] = "artillery_impact";
	bombsfx[4] = "artillery_impact";
	bs = randomInt(bombsfx.size);
	thread playsoundinspace(bombsfx[bs], endorigin);

	bomb hide();
	wait 1;
	bomb delete();*/
}

calcTime(startpos, endpos, speedvalue)
{
	distunit = 1;	// Metres
	speedunit = 1; // Metres per second
	distvalue = distance(startpos, endpos);
	distvalue = int(distvalue * 0.0254); // convert to metres
	timeinsec = (distvalue * distunit) / (speedvalue * speedunit);
	if(timeinsec <= 0) timeinsec = 0.1;
	return timeinsec;
}



flat_origin(org)
{
	rorg = (org[0],org[1],0);
	return rorg;

}

flat_angle(angle)
{
	rangle = (0,angle[1],0);
	return rangle;
}

targetisclose(other, target)
{
	infront = targetisinfront(other, target);
	if(infront)
		dir = 1;
	else
		dir = -1;
	a = flat_origin(other.origin);
	b = a+vector_scale(anglestoforward(flat_angle(other.angles)), (dir*100000));
	point = pointOnSegmentNearestToPoint(a,b, target);
	dist = distance(a,point);
	if (dist < 3000)
		return true;
	else
		return false;
}

targetisinfront(other, target)
{
	forwardvec = anglestoforward(flat_angle(other.angles));
	normalvec = vectorNormalize(flat_origin(target)-other.origin);
	dot = vectordot(forwardvec,normalvec); 
	if(dot > 0)
		return true;
	else
		return false;
}

delete_on_death (ent)
{
	ent endon ("death");
	self waittill ("death");
	if (isdefined (ent))
		ent delete();
}

play_loop_sound_on_entity(alias, offset)
{
	org = spawn ("script_origin",(0,0,0));
	org endon ("death");
	thread delete_on_death (org);
	if (isdefined (offset))
	{
		org.origin = self.origin + offset;
		org.angles = self.angles;
		org linkto (self);
	}
	else
	{
		org.origin = self.origin;
		org.angles = self.angles;
		org linkto (self);
	}

	org playloopsound (alias);
	self waittill ("stop sound" + alias);
	org stoploopsound (alias);
	org delete();
}

callStrike_planeSound( plane, bombsite )
{
	plane thread play_loop_sound_on_entity( "veh_mig29_dist_loop" );
	while( !targetisclose( plane, bombsite ) )
		wait .05;
	plane notify ( "stop sound" + "veh_mig29_dist_loop" );
	plane thread play_loop_sound_on_entity( "veh_mig29_close_loop" );
	while( targetisinfront( plane, bombsite ) )
		wait .05;
	wait .5;
	//plane thread play_sound_in_space( "veh_mig29_sonic_boom" );
	while( targetisclose( plane, bombsite ) )
		wait .05;
	plane notify ( "stop sound" + "veh_mig29_close_loop" );
	plane thread play_loop_sound_on_entity( "veh_mig29_dist_loop" );
	plane waittill( "delete" );
	plane notify ( "stop sound" + "veh_mig29_dist_loop" );
}

playSoundinSpace (alias, origin, master)
{
	org = spawn ("script_origin",(0,0,1));
	if (!isdefined (origin))
		origin = self.origin;
	org.origin = origin;
	if (isdefined(master) && master)
		org playsoundasmaster (alias);
	else
		org playsound (alias);
	wait ( 10.0 );
	org delete();
}

streakNotify( streakVal )
{
	self endon( "disconnect" );

	// wait until any challenges have been processed
//	self waittill( "playerKilledChallengesProcessed" );
	wait .05;
	
	notifyData = spawnStruct();
	notifyData.titleLabel = &"MP_KILLSTREAK_N";
	notifyData.titleText = streakVal;
	
	self maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
	
	iprintln( &"RANK_KILL_STREAK_N", self, streakVal );
}

giveHardpoint( hardpointType, streak )
{
	if ( isDefined( self.pers["hardPointItem"] ) )
		self.pers["hardPointItem"] = undefined;
	
	if( self maps\mp\gametypes\_hardpoints::giveHardpointItem( hardpointType ) )
	{
		self thread hardpointNotify( hardpointType, streak );
	}
}

hardpointNotify( hardpointType, streakVal )
{
	self endon("disconnect");
	
	// wait until any challenges have been processed
//	self waittill( "playerKilledChallengesProcessed" );
	wait .05;
	
	notifyData = spawnStruct();
	notifyData.titleLabel = &"MP_KILLSTREAK_N";
	notifyData.titleText = streakVal;
	notifyData.notifyText = level.hardpointHints[hardpointType];
	notifyData.duration = 4.0;
	notifyData.sound = level.hardpointInforms[hardpointType];
	notifyData.leaderSound = hardpointType;
	
	self maps\mp\gametypes\_hud_message::notifyMessage( notifyData );
}

giveHardpointItem( hardpointType )
{
	if ( level.gameEnded )
		return;
		
	if ( isDefined( self.selectingLocation ) )
		return false;

	if ( !isDefined( level.hardpointItems[hardpointType] ) )
		return false;

	if ( (!isDefined( level.heli_paths ) || !level.heli_paths.size) && ( hardpointType == "helicopter_mp" || hardpointType == "littlebird_mp" || hardpointType == "harrier_mp" ) )
		return false;

	if ( isDefined( self.pers["hardPointItem"] ) )
	{
		if ( level.hardpointItems[hardpointType] < level.hardpointItems[self.pers["hardPointItem"]] )
			return false;
	}
	
	self giveWeapon( "defaultweapon_mp" );
	self giveMaxAmmo( "defaultweapon_mp" );
	self setActionSlot( 4, "weapon", "defaultweapon_mp" );
	self.pers["hardPointItem"] = hardpointType;
	self HardPointItemHud( self.pers["hardPointItem"] );
	
	return true;
}

HardPointItemHud( hardpointType )
{
	if( level.hardcoreMode ) return;
	
	self HardPointItemHudDestroy();
	
	size = undefined;
	if( hardpointType == "harrier_mp" )
		size = 35;
	else if(  hardpointType == "littlebird_mp" )
		size = 32;
	else
		size = 28;
	
	self.hardpointItemHud = newClientHudElem( self );
	self.hardpointItemHud.alpha = .65;
	self.hardpointItemHud.x = 73;
	self.hardpointItemHud.y = 195;
	self.hardpointItemHud.alignX = "center";
	self.hardpointItemHud.alignY = "middle";
	self.hardpointItemHud.horzAlign = "center_safearea";
	self.hardpointItemHud.vertAlign = "center_safearea";
	self.hardpointItemHud.sort = 3;
	self.hardpointItemHud setShader( self getHardPointString(), size, size );
}

HardPointItemHudDestroy()
{
	if( isDefined( self.hardpointItemHud ) ) self.hardpointItemHud destroy();
}

getHardPointString()
{
	if( !isdefined( self.pers["hardPointItem"] ) )	
		return "compass_overlay_map_blank";	
		
	switch( self.pers["hardPointItem"] )
	{
		case "radar_mp":
			return "compass_objpoint_satallite";

		case "counteruav_mp":
			return "compass_objpoint_counteruav";

		case "sentrygun_mp":
			return "hud_icon_minigun";

		case "littlebird_mp":
			return "compass_objpoint_littlebird";

		case "helicopter_mp":
			return "compass_objpoint_helicopter";

		case "airstrike_mp":
			return "compass_objpoint_airstrike";
	
		case "carepackage_mp":
			return "compass_objpoint_carepackage";

		case "harrier_mp":
			return "compass_objpoint_harrier";
	
		case "stealth_mp":
			return "hud_stealth";
	
		case "nuke_mp":
			return "hud_nuke";
	
		case "ac130_mp":
			return "hud_ac130";
	
		case "napalm_mp":
			return "death_napalm";
	
		case "havock_mp":
			return "death_havock";
	
		default:
			return "compass_overlay_map_blank";
	}
}

giveOwnedHardpointItem()
{
	if ( isDefined( self.pers["hardPointItem"] ) )
		self giveHardpointItem( self.pers["hardPointItem"] );
}
	
hardpointItemWaiter()
{
	self endon( "death" );
	self endon( "disconnect" );
	
	lastWeapon = self getCurrentWeapon();
	
	self giveOwnedHardpointItem();
	
	for( ;; )
	{
		self waittill( "weapon_change" );
		
		currentWeapon = self getCurrentWeapon();
		
		switch( currentWeapon )
		{
			case "defaultweapon_mp":
				if( self triggerHardpoint( self.pers["hardPointItem"] ) )
				{
					self thread [[level.onXPEvent]]( "hardpoint" );
					
					self takeWeapon( "defaultweapon_mp" );
					self setActionSlot( 4, "" );
					self.pers["hardPointItem"] = undefined;
					self HardPointItemHudDestroy();
						
					self notify( "hardpoint_used" );
				}
				
				if( lastWeapon != "none" )
					self switchToWeapon( lastWeapon );
				break;

			case "insertion_mp":
				if( self demon\_tactical_insertion::triggerInsertion( currentWeapon ) )
				{
					self takeWeapon( currentWeapon );
					self setActionSlot( 3, "" );
				}
				
				if( lastWeapon != "none" )
					self switchToWeapon( lastWeapon );
				break;
				
			case "none":
				break;	
				
			default:
				lastWeapon = self getCurrentWeapon();
				break;
		}
	}
}

triggerHardPoint( hardpointType )
{
	team = self.pers["team"];
	otherTeam = level.otherTeam[team];
		
	if ( hardpointType == "radar_mp" )
	{
		self thread useRadarItem();
	}
	else if ( hardpointType == "counteruav_mp" )
	{	
		if( isDefined( level.counterUAVinUse[otherTeam] ) )
		{
			self iprintlnBold( level.hardpointHints["counteruav_mp_not_available"] );
			return false;
		}
		
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "counteruav_deployed", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_counteruav_deployed", otherTeam );

			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"HARDPOINTS_COUNTERUAV_DEPLOYED", self, level.counterUAVtime );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "counteruav_deployed" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_counteruav_deployed", undefined, undefined, selfarray );
		}
		
		self thread useCounterUAVItem( otherTeam );
		
	}
	else if ( hardpointType == "airstrike_mp" )
	{
		if( isDefined( level.airstrikeInProgress ) )
		{
			self iPrintLnBold( level.hardpointHints[hardpointType+"_not_available"] );
			return false;
		}

		result = self selectAirstrikeLocation(false);
		
		if ( !isDefined( result ) || !result )
			return false;
	}
	else if ( hardpointType == "carepackage_mp" )
	{
		if( level.carepackInProgress[ self.pers["team"] ] )
		{
			self iprintlnBold( level.hardpointHints["carepackage_mp_not_available"] );
			return false;
		}
		
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "carepackage_deployed", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_carepackage_deployed", otherTeam );

			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"HARDPOINTS_CAREPACKAGE_DEPLOYED", self );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "carepackage_deployed" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_carepackage_deployed", undefined, undefined, selfarray );
		}
		
		self thread demon\_carepackage::setCarePackagePoint();
		
	}
	else if ( hardpointType == "sentrygun_mp" )
	{
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "sentrygun_deployed", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_sentrygun_deployed", otherTeam );

			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"HARDPOINTS_SENTRYGUN_DEPLOYED", self );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "sentrygun_deployed" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_sentrygun_deployed", undefined, undefined, selfarray );
		}
	
		self thread demon\_sentry_turret::sentry_turret();
		
	}
	else if ( hardpointType == "littlebird_mp" )
	{
		if ( isDefined( level.chopper ) || level.harrier_ingame )
		{
			self iPrintLnBold( level.hardpointHints[hardpointType+"_not_available"] );
			return false;
		}
		
		destination = 0;
		random_path = randomint( level.heli_paths[destination].size );
		startnode = level.heli_paths[destination][random_path];
		
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "littlebird_inbound", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_littlebird_inbound", otherTeam );
			
			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"HARDPOINTS_LITTLEBIRD_INBOUND", self );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "littlebird_inbound" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_littlebird_inbound", undefined, undefined, selfarray );
		}
		
		level.littleBird = true;
		thread maps\mp\_helicopter::heli_think( self, startnode, self.pers["team"] );
	}
	else if ( hardpointType == "helicopter_mp" )
	{
		if ( isDefined( level.chopper ) || level.harrier_ingame )
		{
			self iPrintLnBold( level.hardpointHints[hardpointType+"_not_available"] );
			return false;
		}
		
		destination = 0;
		random_path = randomint( level.heli_paths[destination].size );
		startnode = level.heli_paths[destination][random_path];
		
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "helicopter_inbound", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_helicopter_inbound", otherTeam );
			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"MP_HELICOPTER_INBOUND", self );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "helicopter_inbound" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_helicopter_inbound", undefined, undefined, selfarray );
		}
		
		level.littleBird = false;
		thread maps\mp\_helicopter::heli_think( self, startnode, self.pers["team"] );
	}
	else if ( hardpointType == "stealth_mp" )
	{
		if( isDefined( level.airstrikeInProgress ) )
		{
			self iPrintLnBold( level.hardpointHints[hardpointType+"_not_available"] );
			return false;
		}

		result = self selectAirstrikeLocation(true);
		
		if ( !isDefined( result ) || !result )
			return false;
	}
	else if ( hardpointType == "napalm_mp" )
	{
		if( isDefined( level.airstrikeInProgress ) )
		{
			self iPrintLnBold( level.hardpointHints[hardpointType+"_not_available"] );
			return false;
		}

		result = self selectAirstrikeLocation(2);
		
		if ( !isDefined( result ) || !result )
			return false;
	}
	else if ( hardpointType == "ac130_mp" )
	{
		if(isDefined(level.ac130Player))
		{
			self iPrintLnBold( level.hardpointHints[hardpointType+"_not_available"] );
			return false;
		}

		self thread demon\_ac130::ac130_attachPlayer_go();
	}
	else if ( hardpointType == "nuke_mp" )
	{
		self thread demon\_nuke::main();
	}
	else if ( hardpointType == "harrier_mp" )
	{
		if( isDefined( level.chopper ) || level.harrier_ingame  )
		{
			self iprintlnBold( level.hardpointHints["harrier_mp_not_available"] );
			return false;
		}
		
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "harrier_inbound", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_harrier_inbound", otherTeam );

			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"HARDPOINTS_HARRIER_DEPLOYED", self );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "harrier_inbound" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_harrier_inbound", undefined, undefined, selfarray );
		}
		
		random_path = randomint( level.heli_paths[0].size );
		startnode = level.heli_paths[0][random_path];	
			
		self thread maps\mp\_harrier::spawnHarrier( self, startnode, self.pers["team"] );
		
	}
	else if ( hardpointType == "havock_mp" )
	{
		if( isDefined( level.chopper ) || level.havock_ingame  )
		{
			self iprintlnBold( level.hardpointHints["havock_mp_not_available"] );
			return false;
		}
		
		if ( level.teambased )
		{
			maps\mp\gametypes\_globallogic::leaderDialog( "helicopter_inbound", team );
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_helicopter_inbound", otherTeam );

			for ( i = 0; i < level.players.size; i++ )
			{
				player = level.players[i];
				playerteam = player.pers["team"];
				if ( isdefined( playerteam ) )
				{
					if ( playerteam == team )
						player iprintln( &"HARDPOINTS_HELICOPTER_DEPLOYED", self );
				}
			}
		}
		else
		{
			self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "helicopter_inbound" );
			selfarray = [];
			selfarray[0] = self;
			maps\mp\gametypes\_globallogic::leaderDialog( "enemy_helicopter_inbound", undefined, undefined, selfarray );
		}
		
		random_path = randomint( level.heli_paths[0].size );
		startnode = level.heli_paths[0][random_path];	
			
		self thread maps\mp\_havock::spawnhavock( self, startnode, self.pers["team"] );
		
	}
	
	return true;
}

UAVAcquiredPrintAndSound( team, otherteam, callingPlayer, numseconds )
{
	soundFriendly = game["voice"][team]      + game["dialog"]["uav_online"];
	soundEnemy    = game["voice"][otherteam] + game["dialog"]["enemy_uav_online"];
	
	maps\mp\gametypes\_globallogic::leaderDialog( "uav_online", team );
	maps\mp\gametypes\_globallogic::leaderDialog( "enemy_uav_online", otherTeam );
	for ( i = 0; i < level.players.size; i++ )
	{
		player = level.players[i];
		playerteam = player.pers["team"];
		if ( isdefined( playerteam ) )
		{
			if ( playerteam == team )
				player iprintln( &"MP_WAR_RADAR_ACQUIRED", callingPlayer, numseconds );
			else if ( playerteam == otherteam )
				player iprintln( &"MP_WAR_RADAR_ACQUIRED_ENEMY", numseconds  );
		}
	}
}

useRadarItem()
{
	team = self.pers["team"];
	otherTeam = level.otherTeam[team];
	
	assert( isdefined( level.players ) );
	
	if ( level.teambased )
	{
		UAVAcquiredPrintAndSound( team, otherteam, self, level.radarViewTime );

		level notify( "radar_timer_kill_" + team );
		self thread useTeamUAV( team, otherteam );
	}
	else
	{
		self maps\mp\gametypes\_globallogic::leaderDialogOnPlayer( "uav_online" );
		self iprintln( &"MP_WAR_RADAR_ACQUIRED", self, level.radarViewTime );
		
		self notify("radar_timer_kill");
		self thread usePlayerUAV();
	}
}

useTeamUAV( team, otherteam )
{
	level endon( "game_ended" );
	level endon( "radar_timer_kill_" + team );
	
	if( isdefined( level.counterUAVinUse[team] ) ) return;
	
	setTeamRadarWrapper( team, true );
	
	wait level.radarViewTime;
	
	setTeamRadarWrapper( team, false );
	
	printAndSoundOnEveryone( team, otherteam, &"MP_WAR_RADAR_EXPIRED", &"MP_WAR_RADAR_EXPIRED_ENEMY", undefined, undefined, "" );
}

usePlayerUAV( team, otherteam )
{
	level endon("game_ended");
	self endon("radar_timer_kill");
	self endon("disconnect");
	
	self.hasRadar = true;
	self setClientDvar( "ui_uav_client", 1 );
	
	wait level.radarViewTime;
	
	self.hasRadar = false;
	self setClientDvar( "ui_uav_client", 0 );
	
	self iprintln( &"MP_WAR_RADAR_EXPIRED" );
}

setTeamRadarWrapper( team, value )
{
	setTeamRadar( team, value );
	
	dvarval = 0;
	if ( value )
		dvarval = 1;
	setDvar( "ui_uav_" + team, dvarval );
	
	level notify( "radar_status_change", team );
}

selectAirstrikeLocation(isStealth)
{
	if (isStealth==0)
	self beginLocationSelection( "map_artillery_selector", level.artilleryDangerMaxRadius * 1.2 );
	self.selectingLocation = true;
	
	if( isDefined( level.counterUAVinUse[ self.pers["team"] ] ) )
		self thread CreateCounterUAVHud();

	self thread endSelectionOn( "cancel_location" );
	self thread endSelectionOn( "death" );
	self thread endSelectionOn( "disconnect" );
	self thread endSelectionOn( "used" );
	self thread endSelectionOnGameEnd();

	self endon( "stop_location_selection" );
	locations = [];
	location = (0,0,0);
	if (isStealth==1) {
		
		for (i=0; i<4; i++) {
			self beginLocationSelection( "map_artillery_selector", level.artilleryDangerMaxRadius * 1.2 );
			self waittill( "confirm_location", location );
			self iprintlnbold("Location "+(i+1)+" set!");
			wait .25;
			locations[i] = location;
		}
	} else if (isStealth==2) {
		for (i=0; i<2; i++) {
			self beginLocationSelection( "map_artillery_selector", level.artilleryDangerMaxRadius * 1.2 );
			self waittill( "confirm_location", location );
			self iprintlnbold("Location "+(i+1)+" set!");
			wait .25;
			locations[i] = location;
		}
	}
	else {
		self waittill( "confirm_location", location );
	}

	if ( isDefined( level.airstrikeInProgress ) )
	{
		self iPrintLnBold( level.hardpointHints["airstrike_mp_not_available"] );
		self thread stopAirstrikeLocationSelection( false );
		return false;
	}
	if (isStealth==1) {
		for (i=0; i<4; i++)
		self thread finishAirstrikeUsage( locations[i], ::useStealth );
	} else if (isStealth==2) {
		for (i=0; i<2; i++)
		self thread finishAirstrikeUsage( locations[i], ::useNapalm );
	}
	else
		self thread finishAirstrikeUsage( location, ::useAirstrike );
	return true;
}

finishAirstrikeUsage( location, usedCallback )
{
	self notify( "used" );
	wait ( 0.05 );
	self thread stopAirstrikeLocationSelection( false );
	self thread [[usedCallback]]( location );
	return true;
}

endSelectionOn( waitfor )
{
	self endon( "stop_location_selection" );
	
	self waittill( waitfor );

	self thread stopAirstrikeLocationSelection( (waitfor == "disconnect") );
}

endSelectionOnGameEnd()
{
	self endon( "stop_location_selection" );
	
	level waittill( "game_ended" );
	
	self thread stopAirstrikeLocationSelection( false );
}

stopAirstrikeLocationSelection( disconnected )
{
	if ( !disconnected )
	{
		self endLocationSelection();
		self.selectingLocation = undefined;
	}
	
	self notify( "stop_location_selection" );
	
	self destroyCounterUAVHud();
}

useAirstrike( pos )
{
	trace = bullettrace( self.origin + (0,0,10000), self.origin, false, undefined );
	pos = (pos[0], pos[1], trace["position"][2] - 514);

	thread doAirstrike( 0, pos, self, self.pers["team"] );
}

useStealth( pos )
{
	trace = bullettrace( self.origin + (0,0,10000), self.origin, false, undefined );
	pos = (pos[0], pos[1], trace["position"][2] - 514);

	thread doAirstrike( 1, pos, self, self.pers["team"] );
}

useNapalm( pos )
{
	trace = bullettrace( self.origin + (0,0,10000), self.origin, false, undefined );
	pos = (pos[0], pos[1], trace["position"][2] - 514);

	thread doAirstrike( 2, pos, self, self.pers["team"] );
}

CreateCounterUAVHud()
{
	self destroyCounterUAVHud();
	
	self createHudElement( "counterUAV_overlay1", 0, 0, "center", "middle", "center_safearea", "center_safearea", true, "counter_radar_grain", 396, 396, 5, 0.8, 1, 1, 1 );
	self createHudElement( "counterUAV_overlay2", 0, 0, "center", "middle", "center_safearea", "center_safearea", true, "white", 396, 396, 1, 0.8, 1, 4, 1 );
}

destroyCounterUAVHud()
{
	self deleteHudElementbyName( "counterUAV_overlay1" );
	self deleteHudElementbyName( "counterUAV_overlay2" );
}

useCounterUAVItem( team )
{
	if( level.teambased )
	{
		level notify( "counteruav_timer_kill_" + team );
		self thread useTeamCounterUAV( team );
	}
	else
	{
		self notify( "counteruav_timer_kill" );
		self thread usePlayerCounterUAV();
	}
}

usePlayerCounterUAV()
{
	level endon( "game_ended" );
	self endon( "counteruav_timer_kill" );
	self endon( "disconnect" );
	
	level.PlayercounterUAVinUse = true;
	
	self.hasCounterRadar = true;

	for( i=0; i < level.players.size; i++ )
		if( level.players[i] != self )
		{
			player = level.players[i];
			player setClientDvars( "ui_counteruav_client", 1, "scr_demon_show_enemy_pings", 0, "ui_hud_showobjicons", 0 );
		}
	
	wait( level.counterUAVtime );
	
	self.hasCounterRadar = true;

	for( i=0; i < level.players.size; i++ )
		if( level.players[i] != self )
		{
			player = level.players[i];
			player setClientDvars( "ui_counteruav_client", 0, "scr_demon_show_enemy_pings", level.show_enemy_pings, "ui_hud_showobjicons", level.show_compass_waypoints );
		}
	
	self iprintln( "Counter UAV Expired" );
	
	level.PlayercounterUAVinUse = undefined;
}

useTeamCounterUAV( team )
{	
	level endon( "game_ended" );
	level endon( "counteruav_timer_kill_" + team );
	
	level.counterUAVinUse[team] = true;
	
	setTeamRadarWrapper( team, false );
	
	setDvar( "ui_jammeduav_" + team, 1 );
	
	for( i=0; i < level.players.size; i++ )
		if( level.players[i].pers["team"] == team )
			level.players[i] setClientDvars( "scr_demon_show_enemy_pings", 0, "ui_jammeduav_" + team, 1, "ui_hud_showobjicons", 0 );
	
	wait( level.counterUAVtime );
	
	setDvar( "ui_jammeduav_" + team, 0 );
	
	for( i=0; i < level.players.size; i++ )
		if( level.players[i].pers["team"] == team  )
			level.players[i] setClientDvars( "scr_demon_show_enemy_pings", level.show_enemy_pings, "ui_jammeduav_" + team, 0, "ui_hud_showobjicons", level.show_compass_waypoints );
	
	if( self.pers["team"] != team )
		self iprintln( "Counter UAV Expired" );
	
	level.counterUAVinUse[team] = undefined;

}

/******************************************************
	Necessary because the hud display for the hardpoint 
	keeps disappearing for some strange reason
*******************************************************/
checkHardpointWeapon()
{
	self endon( "death" );
	self endon( "disconnect" );
	
	for( ;; )
	{
		if( isdefined( self.pers["hardPointItem"] ) && !self HasWeapon( "defaultweapon_mp" ) )
			self giveHardpointItem( self.pers["hardPointItem"] );
		
		wait( 0.05 );
	}
}