#using scripts\shared\array_shared;
#using scripts\shared\gameobjects_shared;
#using scripts\shared\hud_message_shared;
#using scripts\shared\hud_util_shared;
#using scripts\shared\math_shared;
#using scripts\shared\persistence_shared;
#using scripts\shared\rank_shared;
#using scripts\shared\scoreevents_shared;
#using scripts\shared\util_shared;
#using scripts\shared\weapons\_weapon_utils;

    	   	                                                                                                                                         	                                	                                                                                                                                                                                                                                                                                                                                                                    	        	     	              	    	   	               	                                              	                                                           	                               	                     	                                                                                                           	                                                                 	                                                              	                                                                                                                                             	                            	                                     	                                       	                                                                                                              	   	                  	       	                                                    	                   	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            	                                                                                                 	                                    	                                                                                        	           	                        	                                            	                                             	                                                   	                                                             	                                                         	                                                                    	                                                                                                                                                                                                                                	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  	    	         	                                                              	                                                          	                                   	                                   	                                                    	                                       	                                           	     	                                                                                                                                                                                                                                                      	                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         	                                                               	        	                                                                                                                              	                                                                                                                     	                               	                                                      	                          

#using scripts\mp\gametypes\_globallogic;
#using scripts\mp\gametypes\_globallogic_audio;
#using scripts\mp\gametypes\_globallogic_score;
#using scripts\mp\gametypes\_loadout;
#using scripts\mp\gametypes\_spawning;
#using scripts\mp\gametypes\_spawnlogic;
#using scripts\mp\gametypes\_wager;

#using scripts\mp\_util;

/*
	Deathmatch
	Objective: 	Score points by eliminating other players
	Map ends:	When one player reaches the score limit, or time limit is reached
	Respawning:	No wait / Away from other players

	Level requirements
	------------------
		Spawnpoints:
			classname		mp_wager_spawn
			All players spawn from these. The spawnpoint chosen is dependent on the current locations of enemies at the time of spawn.
			Players generally spawn away from enemies.

		Spectator Spawnpoints:
			classname		mp_global_intermission
			Spectators spawn from these and intermission is viewed from these positions.
			Atleast one is required, any more and they are randomly chosen between.

	Level script requirements
	-------------------------
		Team Definitions:
			game["allies"] = "marines";
			game["axis"] = "nva";
			Because Deathmatch doesn't have teams with regard to gameplay or scoring, this effectively sets the available weapons.

		If using minefields or exploders:
			load::main();

	Optional level script settings
	------------------------------
		Soldier Type and Variation:
			game["soldiertypeset"] = "seals";
			This sets what character models are used for each nationality on a particular map.

			Valid settings:
				soldiertypeset	seals
*/

//#define SAS_PRIMARY_WEAPON "crossbow" // brian barnes - crossbow weapon deleted, hoping just swapping this to a supported weapon will work




#precache( "string", "OBJECTIVES_SAS" );
#precache( "string", "OBJECTIVES_SAS_SCORE" );
#precache( "string", "OBJECTIVES_SAS_HINT" );
#precache( "string", "MP_HUMILIATION" );
#precache( "string", "MP_HUMILIATED" );
#precache( "string", "MP_BANKRUPTED" );
#precache( "string", "MP_BANKRUPTED_OTHER" );

function main()
{
	globallogic::init();
	
	level.weapon_SAS_PRIMARY_WEAPON = GetWeapon( "special_crossbow" );
	level.weapon_SAS_SECONDARY_WEAPON = GetWeapon( "knife_ballistic" );
	level.weapon_SAS_PRIMARY_GRENADE_WEAPON = GetWeapon( "hatchet" );

	util::registerTimeLimit( 0, 1440 );
	util::registerScoreLimit( 0, 5000 );
	util::registerRoundLimit( 0, 10 );
	util::registerRoundWinLimit( 0, 10 );
	util::registerNumLives( 0, 100 );

	level.onStartGameType =&onStartGameType;
	level.onPlayerDamage =&onPlayerDamage;
	level.onPlayerKilled =&onPlayerKilled;
	level.onPlayerScore = &onPlayerScore;
//	level.onWagerAwards =&onWagerAwards;
	level.pointsPerPrimaryKill = GetGametypeSetting( "pointsPerPrimaryKill" );
	level.pointsPerSecondaryKill = GetGametypeSetting( "pointsPerSecondaryKill" );
	level.pointsPerPrimaryGrenadeKill = GetGametypeSetting( "pointsPerPrimaryGrenadeKill" );
	level.pointsPerMeleeKill = GetGametypeSetting( "pointsPerMeleeKill" );
	level.setBacks = GetGametypeSetting( "setbacks" );
	
	switch ( GetGametypeSetting( "gunSelection" ) )
	{
		case 0:
			level.setBackWeapon = undefined;
			break;
			
		case 1:
			level.setBackWeapon = level.weapon_SAS_PRIMARY_GRENADE_WEAPON;
			break;
			
		case 2:
			level.setBackWeapon = level.weapon_SAS_PRIMARY_WEAPON;
			break;
			
		case 3:
			level.setBackWeapon = level.weapon_SAS_SECONDARY_WEAPON;
			break;
			
		default:
			assert( true, "Invalid setting for gunSelection" );
			break;
	}

	game["dialog"]["gametype"] = "sns_start";
	game["dialog"]["wm_humiliation"] = "mpl_wager_bankrupt";
	game["dialog"]["wm_humiliated"] = "sns_hum";
	
	gameobjects::register_allowed_gameobject( level.gameType );

	level.giveCustomLoadout =&giveCustomLoadout;
	
	sas_perks = [];
	if ( !isdefined( sas_perks ) ) sas_perks = []; else if ( !IsArray( sas_perks ) ) sas_perks = array( sas_perks ); sas_perks[sas_perks.size]="specialty_fastweaponswitch";;
	if ( !isdefined( sas_perks ) ) sas_perks = []; else if ( !IsArray( sas_perks ) ) sas_perks = array( sas_perks ); sas_perks[sas_perks.size]="specialty_jetcharger";;
	if ( !isdefined( sas_perks ) ) sas_perks = []; else if ( !IsArray( sas_perks ) ) sas_perks = array( sas_perks ); sas_perks[sas_perks.size]="specialty_tracker";;
	level.sas_perks = sas_perks;
	
	sas_gadgets = [];
	if ( !isdefined( sas_gadgets ) ) sas_gadgets = []; else if ( !IsArray( sas_gadgets ) ) sas_gadgets = array( sas_gadgets ); sas_gadgets[sas_gadgets.size]="gadget_camo";;
	if ( !isdefined( sas_gadgets ) ) sas_gadgets = []; else if ( !IsArray( sas_gadgets ) ) sas_gadgets = array( sas_gadgets ); sas_gadgets[sas_gadgets.size]="gadget_clone";;
	level.weapon_SAS_DEFAULT_GADGET = array::random( sas_gadgets );
	
	globallogic::setvisiblescoreboardcolumns( "pointstowin", "kills", "deaths", "tomahawks", "humiliated" ); 
}

function giveCustomLoadout()
{
	self notify( "sas_spectator_hud" );
	
	defaultWeapon = level.weapon_SAS_PRIMARY_WEAPON;
	loadout::setClassNum( self.curClass );

	self wager::setup_blank_random_player( true, true, defaultWeapon );
	
	self givePerks();
	
	self GiveWeapon( defaultWeapon );
	self SetWeaponAmmoClip( defaultWeapon, 6 );
	self SetWeaponAmmoStock( defaultWeapon, 6 );
	self.primaryLoadoutWeapon = defaultWeapon;

	secondaryWeapon = level.weapon_SAS_SECONDARY_WEAPON;
	self GiveWeapon( secondaryWeapon );
	self SetWeaponAmmoStock( secondaryWeapon, 2 );
	self.secondaryLoadoutWeapon = defaultWeapon;

	offhandPrimary = level.weapon_SAS_PRIMARY_GRENADE_WEAPON;
	self SetOffhandPrimaryClass( offhandPrimary );
	self GiveWeapon( offhandPrimary );
	self SetWeaponAmmoClip( offhandPrimary, 1 );
	self SetWeaponAmmoStock( offhandPrimary, 1 );
	self.grenadeTypePrimary = offhandPrimary;
	self.grenadeTypePrimaryCount = 1;
	
	secondaryOffhand = GetWeapon( "null_offhand_secondary" );
	secondaryOffhandCount = 0;
	self GiveWeapon( secondaryOffhand );
	self SetWeaponAmmoClip( secondaryOffhand, secondaryOffhandCount );
	self SwitchToOffhand( secondaryOffhand );
	self.grenadeTypeSecondary = secondaryOffhand;
	self.grenadeTypeSecondaryCount = secondaryOffhandCount;
	
	self GiveWeapon( level.weaponBaseMelee );
	
	self giveDefaultGadget();

	self SwitchToWeapon( defaultWeapon );
	self SetSpawnWeapon( defaultWeapon );
	
	self.killsWithSecondary = 0;
	self.killsWithPrimary = 0;
	self.killsWithBothAwarded = false;
	
	return defaultWeapon;
}

function giveDefaultGadget()
{
	specialOffhand = self.sas_matchGadget;
	resetCharge = false;
	
	if ( !isdefined( specialOffhand ) )
	{
		specialOffhand = GetWeapon( level.weapon_SAS_DEFAULT_GADGET );
		resetCharge = true;
	}
	
	specialOffhandCount = specialOffhand.startammo;
	self GiveWeapon( specialOffhand );
		
	self SetWeaponAmmoClip( specialOffhand, specialOffhandCount );
	self SwitchToOffhand( specialOffhand );
	self.grenadeTypeSpecial = specialOffhand;
	self.grenadeTypeSpecialCount = specialOffhandCount;

	if ( ( isdefined( resetCharge ) && resetCharge ) )
	{
		slot = self GadgetGetSlot( specialOffhand );
		self GadgetPowerSet( slot, 0 );
	}
	
	self.sas_matchGadget = specialOffhand;
}

function givePerks()
{
	foreach ( perkName in level.sas_perks )
	{
		self SetPerk( perkName );
	}
}

function onPlayerDamage( eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, weapon, vPoint, vDir, sHitLoc, psOffsetTime )
{
	if ( ( weapon == level.weapon_SAS_PRIMARY_WEAPON ) && ( sMeansOfDeath == "MOD_IMPACT" ) )
	{
		if ( isdefined( eAttacker ) && IsPlayer( eAttacker ) )
		{
			if ( !isdefined( eAttacker.pers["sticks"] ) )
				eAttacker.pers["sticks"] = 1;
			else
				eAttacker.pers["sticks"]++;
			eAttacker.sticks = eAttacker.pers["sticks"];
		}
	}
	
	return iDamage;
}

function onPlayerScore( event, player, victim )
{
	score = player.pers["pointstowin"];
	
	if ( !level.rankedMatch )
	{
		player thread rank::updateRankScoreHUD( score - player.pers["score"] );
	}

	player.pers["score"] = score;
	player.score = player.pers["score"];
	recordPlayerStats( player, "score" , player.pers["score"] );
}

function onPlayerKilled( eInflictor, attacker, iDamage, sMeansOfDeath, weapon, vDir, sHitLoc, psOffsetTime, deathAnimDuration )
{	
	if ( isdefined( attacker ) && IsPlayer( attacker ) && attacker != self )
	{
		if ( weapon_utils::isMeleeMOD( sMeansOfDeath ) )
		{
			//should probably make this a custom setting
			attacker globallogic_score::givePointsToWin( level.pointsPerMeleeKill );	
			onPlayerScore( undefined, attacker, undefined );
		}
		else if ( weapon == level.weapon_SAS_PRIMARY_WEAPON )
		{
			attacker.killsWithPrimary++;
			if ( attacker.killsWithBothAwarded == false && attacker.killsWithSecondary > 0 ) 
			{
				attacker.killsWithBothAwarded = true;
			}
			attacker globallogic_score::givePointsToWin( level.pointsPerPrimaryKill );
			onPlayerScore( undefined, attacker, undefined );
		}
		else if ( weapon == level.weapon_SAS_PRIMARY_GRENADE_WEAPON )
		{
			attacker globallogic_score::givePointsToWin( level.pointsPerPrimaryGrenadeKill );
			onPlayerScore( undefined, attacker, undefined );
		}
		else
		{
			if ( weapon == level.weapon_SAS_SECONDARY_WEAPON ) // make sure this is not a kill by destructible
			{
				attacker.killsWithSecondary++;
				if ( attacker.killsWithBothAwarded == false && attacker.killsWithPrimary > 0 ) 
				{
					attacker.killsWithBothAwarded = true;
				}
			}
			
			attacker globallogic_score::givePointsToWin( level.pointsPerSecondaryKill );
			onPlayerScore( undefined, attacker, undefined );
		}
		
		if ( isdefined( level.setBackWeapon ) && ( weapon == level.setBackWeapon ) )
		{
			self.pers["humiliated"]++;
			self.humiliated = self.pers["humiliated"];
						
			if ( level.setBacks == 0 )
			{
				self globallogic_score::setPointsToWin( 0 );
				onPlayerScore( undefined, self, undefined );
			}
			else
			{
				self globallogic_score::givePointsToWin( level.setBacks * -1 );
				onPlayerScore( undefined, self, undefined );
			}
			attacker PlayLocalSound( "mpl_fracture_sting_moved" );
			attacker AddPlayerStatWithGameType( "HUMILIATE_ATTACKER", 1 );
			self thread playerHumiliation();
		}
	}
	else
	{
		self.pers["humiliated"]++;
		self.humiliated = self.pers["humiliated"];
		if ( level.setBacks == 0 )
		{
			self globallogic_score::setPointsToWin( 0 );
			onPlayerScore( undefined, self, undefined );
		}
		else
		{
			self globallogic_score::givePointsToWin( level.setBacks * -1 );
			onPlayerScore( undefined, self, undefined );
		}
		self thread playerHumiliation();
	}
}

function playerHumiliation()
{
	self endon( "disconnect" );
	self endon( "death" );
	
	self AddPlayerStatWithGameType( "HUMILIATE_VICTIM", 1 );
	
	self waittill( "spawned_player" );
		
	self PlayLocalSound( "mpl_assassination_sting" );
	
	humHud = self hud::createFontString( "default", 2.5 );
	humHud hud::setPoint( "CENTER", undefined, 0, -100 );
	humHud.label = &"MP_HUMILIATED";
	humHud.x = 0;
	humHud.archived = true;
	humHud.alpha = 1;
	humHud.glowAlpha = 0;
	humHud.hidewheninmenu = false;
	
	self thread playerHumiliationCleanup( humHud );
	
	wait 0.1;
	
	humHud FadeOverTime( 0.2 );
	humHud.color = ( 1, 0, 0 );
	humHud ChangeFontScaleOverTime( 0.2 );
	humHud.fontScale = 3;
	wait 0.5;
	
	humHud FadeOverTime( 0.5 );
	humHud.color = ( 1, 1, 1 );
	humHud ChangeFontScaleOverTime( 0.5 );
	humHud.fontScale = 2.5;
	wait 1.0;
	
	self notify( "humHudDestroyed" );
	humHud Destroy();
}

function playerHumiliationCleanup( humHud )
{
	self endon( "humHudDestroyed" );
	
	self util::waittill_any( "disconnect", "death" );
	
	if ( isdefined( humHud ) )
		humHud Destroy();
}

function setupTeam( team )
{
	util::setObjectiveText( team, &"OBJECTIVES_SAS" );
	if ( level.splitscreen )
	{
		util::setObjectiveScoreText( team, &"OBJECTIVES_SAS" );
	}
	else
	{
		util::setObjectiveScoreText( team, &"OBJECTIVES_SAS_SCORE" );
	}
	util::setObjectiveHintText( team, &"OBJECTIVES_SAS_HINT" );
	
	spawnlogic::add_spawn_points( team, "mp_dm_spawn" );
	spawnlogic::place_spawn_points( "mp_dm_spawn_start" );
	
	level.spawn_start = spawnlogic::get_spawnpoint_array( "mp_dm_spawn_start" );
}

function onStartGameType()
{
//	SetDvar( "scr_xpscalemp", 0 );
	SetDvar( "tu29_gametypeOverridesGadget", true );
	
	setClientNameMode("auto_change");

	// now that the game objects have been deleted place the influencers
	spawning::create_map_placed_influencers();
	
	level.spawnMins = ( 0, 0, 0 );
	level.spawnMaxs = ( 0, 0, 0 );
	
	foreach( team in level.teams )
	{
		setupTeam( team );
	}

	spawning::updateAllSpawnPoints();
	
	level.mapCenter = math::find_box_center( level.spawnMins, level.spawnMaxs );
	setMapCenter( level.mapCenter );

	spawnpoint = spawnlogic::get_random_intermission_point();
	setDemoIntermissionPoint( spawnpoint.origin, spawnpoint.angles );

	// use the new spawn logic from the start
	level.useStartSpawns = false;
	
	level.displayRoundEndText = false;
	
	if ( isdefined( game["roundsplayed"] ) && game["roundsplayed"] > 0 )
	{
		game["dialog"]["gametype"] = undefined;
		game["dialog"]["offense_obj"] = undefined;
		game["dialog"]["defense_obj"] = undefined;
	}
}

function onWagerAwards()
{
	tomahawks = self globallogic_score::getPersStat( "tomahawks" );
	if ( !isdefined( tomahawks ) )
		tomahawks = 0;
	self persistence::set_after_action_report_stat( "wagerAwards", tomahawks, 0 );
	
	sticks = self globallogic_score::getPersStat( "sticks" );
	if ( !isdefined( sticks ) )
		sticks = 0;
	self persistence::set_after_action_report_stat( "wagerAwards", sticks, 1 );
	
	bestKillstreak = self globallogic_score::getPersStat( "best_kill_streak" );
	if ( !isdefined( bestKillstreak ) )
		bestKillstreak = 0;
	self persistence::set_after_action_report_stat( "wagerAwards", bestKillstreak, 2 );
}
