/*
	_bot_loadout
	Author: INeedGames
	Date: 12/20/2020
	Loadout stuff
*/

#include common_scripts\utility;
#include maps\mp\_utility;
#include maps\mp\gametypes\_hud_util;
#include maps\mp\bots\_bot_utility;

/*
	Gives the bot loadout
*/
bot_give_loadout()
{
	self bot_giveKillstreaks();
		
	self clearPerks();
		
	self SetPlayerRenderOptions( int( self.pers["bot"]["class_render_opts"] ) );
		
	if (!isDefined(self.bot))
		self.bot = [];
		
	self.bot[ "specialty1" ] = "specialty_null";
	self.bot[ "specialty2" ] = "specialty_null";
	self.bot[ "specialty3" ] = "specialty_null";
		
	if (self.pers["bot"]["class_perk1"] != "" && GetDvarInt( #"scr_game_perks" ) )
	{
		self.bot[ "specialty1" ] = self.pers["bot"]["class_perk1"];
		
		id = bot_perk_from_reference_full(self.pers["bot"]["class_perk1"]);
		tokens = strtok(id["reference"], "|");
		
		for (i = 0; i < tokens.size; i++)
			self setPerk(tokens[i]);
	}
		
	switch( self.pers["bot"]["class_perk1"] )
	{
		case "perk_ghost":
		case "perk_ghost_pro":
			self.cac_body_type = "camo_mp";
			break;

		case "perk_hardline":
		case "perk_hardline_pro":
			self.cac_body_type = "hardened_mp";
			break;

		case "perk_flak_jacket":
		case "perk_flak_jacket_pro":
			self.cac_body_type = "ordnance_disposal_mp";
			break;

		case "perk_scavenger":
		case "perk_scavenger_pro":
			self.cac_body_type = "utility_mp";
			break;

		case "perk_lightweight":
		case "perk_lightweight_pro":
		default:
			self.cac_body_type = "standard_mp";
			break;
	}
		
	self.cac_head_type = self maps\mp\gametypes\_armor::get_default_head();
	self.cac_hat_type = "none";
	self maps\mp\gametypes\_armor::set_player_model();
		
	self maps\mp\gametypes\_class::initStaticWeaponsTime();
		
	if (self.pers["bot"]["class_perk2"] != "" && GetDvarInt( #"scr_game_perks" ))
	{
		self.bot[ "specialty2" ] = self.pers["bot"]["class_perk2"];
		
		id = bot_perk_from_reference_full(self.pers["bot"]["class_perk2"]);
		tokens = strtok(id["reference"], "|");
		
		for (i = 0; i < tokens.size; i++)
			self setPerk(tokens[i]);
	}
		
	if (self.pers["bot"]["class_perk3"] != "" && GetDvarInt( #"scr_game_perks" ))
	{
		self.bot[ "specialty3" ] = self.pers["bot"]["class_perk3"];
		
		id = bot_perk_from_reference_full(self.pers["bot"]["class_perk3"]);
		tokens = strtok(id["reference"], "|");
		
		for (i = 0; i < tokens.size; i++)
			self setPerk(tokens[i]);
	}
		
		
	self takeAllWeapons();
	if (getDvarInt("bots_play_knife"))
		self GiveWeapon( "knife_mp" );

	weap = self.pers["bot"]["class_primary"];
	if(weap == "")
		weap = "ak47_mp";
		
	primaryTokens = strtok( self.pers["bot"]["class_primary"], "_" );
	self.pers["primaryWeapon"] = primaryTokens[0];
		
	weap = self.pers["bot"]["class_primary"];
	if(GetDvarInt( #"scr_disable_attachments" ))
		weap = self.pers["primaryWeapon"] + "_mp";
		
	self GiveWeapon( weap, 0, int( self.pers["bot"]["class_primary_opts"] ) );
		
	if ( self hasPerk( "specialty_extraammo" ) )
		self giveMaxAmmo( weap );

	if (!getDVarint("bots_play_fire"))
	{
		self SetWeaponAmmoClip(weap, 0);
		self SetWeaponAmmoStock(weap, 0);
	}
		
	if(self.pers["bot"]["class_secondary"] != "")
	{
		self GiveWeapon( self.pers["bot"]["class_secondary"], 0, int( self.pers["bot"]["class_secondary_opts"] ) );
		if ( self hasPerk( "specialty_extraammo" ) )
			self giveMaxAmmo( self.pers["bot"]["class_secondary"] );

		if (!getDVarint("bots_play_fire"))
		{
			self SetWeaponAmmoClip(self.pers["bot"]["class_secondary"], 0);
			self SetWeaponAmmoStock(self.pers["bot"]["class_secondary"], 0);
		}
	}
		
	self SetActionSlot( 3, "altMode" );
	self SetActionSlot( 4, "" );
		
	if(self.pers["bot"]["class_equipment"] != "" && self.pers["bot"]["class_equipment"] != "weapon_null_mp" && !GetDvarInt( #"scr_disable_equipment" ))
	{
		self GiveWeapon( self.pers["bot"]["class_equipment"] );
			
		self maps\mp\gametypes\_class::setWeaponAmmoOverall( self.pers["bot"]["class_equipment"], 1 );
			
		self SetActionSlot( 1, "weapon", self.pers["bot"]["class_equipment"] );
	}
		
	if(self.pers["bot"]["class_lethal"] != "")
	{
		self GiveWeapon( self.pers["bot"]["class_lethal"] );
		
		if(self hasPerk("specialty_twogrenades"))
			self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 2 );
		else
			self SetWeaponAmmoClip( self.pers["bot"]["class_lethal"], 1 );
		
		self SwitchToOffhand( self.pers["bot"]["class_lethal"] );
	}
		
	if(self.pers["bot"]["class_tacticle"] != "")
	{
		self giveWeapon( self.pers["bot"]["class_tacticle"] );
		
		if(self.pers["bot"]["class_tacticle"] == "willy_pete_mp")
			self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 1 );
		else if(self hasPerk("specialty_twogrenades"))
			self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 3 );
		else
			self SetWeaponAmmoClip( self.pers["bot"]["class_tacticle"], 2 );
		
		self setOffhandSecondaryClass( self.pers["bot"]["class_tacticle"] );
	}
		
	self thread fixSecondarySwitch(weap);
}

/*
	Fixes the weapon on spawn for the bot
*/
fixSecondarySwitch(weap)
{
	self endon("death");
	self endon("disconnect");
	self switchToWeapon(weap);
	self setSpawnWeapon(weap);
	wait 0.05;
	self switchToWeapon(weap);
	self setSpawnWeapon(weap);
}

/*
	Gets the prestige
*/
bot_get_prestige()
{
	p_dvar = getDvarInt("bots_loadout_prestige");
	p = 0;

	if (p_dvar == -1)
	{
		for (i = 0; i < level.players.size; i++)
		{
			player = level.players[i];

			if (!isDefined(player.team))
				continue;

			if (player is_bot())
				continue;

			p = player maps\mp\gametypes\_persistence::statGet( "plevel" );
			break;
		}
	}
	else if (p_dvar == -2)
	{
		p = randomInt(17);
	}
	else
	{
		p = p_dvar;
	}

	self.pers["bot"]["prestige"] = p;
}

/*
	Gives the rank to the bot
*/
bot_rank()
{
	self endon("disconnect");
		
	wait 0.05;
		
	self.pers["rankxp"] = self.pers["bot"]["rankxp"];
	rankId = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] );
	prestige = self.pers["bot"]["prestige"];

	self.pers["rank"] = rankId;
	self.pers["prestige"] = prestige;
	self.pers["plevel"] = prestige;
	self setRank( rankId, prestige );
		
	if(!level.gameEnded)
		level waittill("game_ended");
		
	self.pers["bot"]["rankxp"] = self.pers["rankxp"];
}

/*
	Set the bot's class
*/
bot_set_class()
{
	self.pers["bot"]["class_render_opts"] = 0;
		
	self.pers["bot"]["class_primary"] = "";
	self.pers["bot"]["class_primary_opts"] = 0;
	self.pers["bot"]["class_secondary"] = "";
	self.pers["bot"]["class_secondary_opts"] = 0;
		
	self.pers["bot"]["class_lethal"] = "";
	self.pers["bot"]["class_tacticle"] = "";
	self.pers["bot"]["class_equipment"] = "";
		
	self.pers["bot"]["class_perk1"] = "";
	self.pers["bot"]["class_perk2"] = "";
	self.pers["bot"]["class_perk3"] = "";
		
	self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points_org" ];//refund prev payments for class
		
	rank = self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] );

	if ( !level.onlineGame )
	{
		rank = level.maxRank;
	}
		
	if (rank < 3 || (randomint(100) < 3 && !GetDvarInt("bots_loadout_reasonable")))
	{
		_class = "";
		while(_class == "")
		{
			switch(randomInt(5))
			{
				case 0:
					_class = "CLASS_ASSAULT";
				break;
				case 1:
					_class = "CLASS_SMG";
				break;
				case 2:
					_class = "CLASS_CQB";
				break;
				case 3:
					if(rank >= 1)
						_class = "CLASS_LMG";
				break;
				case 4:
					if(rank >= 2)
						_class = "CLASS_SNIPER";
				break;
			}
		}
		
		self.pers["bot"]["class_primary"] = level.classWeapons["axis"][_class][0];
		self.pers["bot"]["class_secondary"] = level.classSidearm["axis"][_class];
		self.pers["bot"]["class_perk1"] = level.default_perkIcon[_class][ 0 ];
		self.pers["bot"]["class_perk2"] = level.default_perkIcon[_class][ 1 ];
		self.pers["bot"]["class_perk3"] = level.default_perkIcon[_class][ 2 ];
		self.pers["bot"]["class_equipment"] = level.default_equipment[ _class ][ "type" ];
		self.pers["bot"]["class_lethal"] = level.classGrenades[_class]["primary"]["type"];
		self.pers["bot"]["class_tacticle"] = level.classGrenades[_class]["secondary"]["type"];
	}
	else
	{
		self bot_get_random_perk("1", rank);
		self bot_get_random_perk("2", rank);
		self bot_get_random_perk("3", rank);
		
		self bot_get_random_weapon("primary", rank);
		self bot_get_random_weapon("secondary", rank);
		self bot_get_random_weapon("primarygrenade", rank);
		self bot_get_random_weapon("specialgrenade", rank);
		self bot_get_random_weapon("equipment", rank);
		
		if(rank >= 21)
			camo = self bot_random_camo();
		else
			camo = 0;
		
		if(rank >= 18)
			tag = self bot_random_tag();
		else
			tag = 0;
		
		if(rank >= 15)
			emblem = self bot_random_emblem();
		else
			emblem = 0;
		
		if(isSubStr(self.pers["bot"]["class_primary"], "_elbit_") || isSubStr(self.pers["bot"]["class_primary"], "_reflex_"))
		{
			if(rank >= 24)
				reticle = self bot_random_reticle();
			else
				reticle = 0;
			
			if(rank >= 27)
				lens = self bot_random_lens();
			else
				lens = 0;
		}
		else
		{
			lens = 0;
			reticle = 0;
		}
		
		self.pers["bot"]["class_primary_opts"] = self calcWeaponOptions( camo, lens, reticle, tag, emblem );
		
		if(rank >= 30)
			face = self bot_random_face();
		else
			face = 0;
		
		self.pers["bot"]["class_render_opts"] = self calcPlayerOptions( face, 0 );
	}
		
	if(!GetDvarInt("bots_loadout_allow_op") && isSubStr(self.pers["bot"]["class_perk3"], "perk_second_chance"))
		self.pers["bot"]["class_perk3"] = "";
}

/*
	Set the bot's a random weapon for the slot
*/
bot_get_random_weapon(slot, rank)
{
	if(!isDefined(level.bot_weapon_ids))
		level.bot_weapon_ids = [];
		
	if ( !IsDefined( level.bot_weapon_ids[ slot ] ) )
	{
		level.bot_weapon_ids[ slot ] = [];

		keys = GetArrayKeys( level.tbl_weaponIDs );

		for ( i = 0; i < keys.size; i++ )
		{
			key = keys[i];
			id = level.tbl_weaponIDs[ key ];

			if ( id[ "reference" ] == "weapon_null" )
				continue;
			
			if ( isSubStr(id[ "reference" ], "dw") )
				continue;

			if ( id[ "cost" ] == "-1" )
				continue;

			if ( id[ "slot" ] == slot )
			{
				level.bot_weapon_ids[ slot ][ level.bot_weapon_ids[ slot ].size ] = id;
			}
		}
	}
		
	reason = GetDvarInt("bots_loadout_reasonable");
	diff = self GetBotDiffNum();

	if(slot == "equipment" && self.pers["bot"]["cod_points"] < 2000)
		return;
		
	for(;;)
	{
		id = PickRandom( level.bot_weapon_ids[ slot ] );
		if (!isDefined(id))
			return;
		
		if(!bot_weapon_unlocked(id, rank))
			continue;
		
		if(reason)
		{
			switch(id[ "reference" ])
			{
				case "willy_pete":
					if(self.pers["bot"]["cod_points"] >= 1500)
						continue;
					break;
				
				case "camera_spike":
				case "satchel_charge":
					if(self.pers["bot"]["cod_points"] >= 2500)
						continue;
					break;

				case "nightingale":
				case "tabun_gas":
				case "rottweil72":
				case "hs10":
				case "dragunov":
				case "wa2000":
				case "hk21":
				case "rpk":
				case "m14":
				case "fnfal":
				case "uzi":
				case "skorpion":
				case "pm63":
				case "kiparis":
				case "mac11":
				case "ithaca":
					continue;
			}
		}
		
		if ( id[ "reference" ] == "hatchet" && RandomInt( 100 ) > 20 )
		{
			continue;
		}

		if ( id[ "reference" ] == "willy_pete" && RandomInt( 100 ) > 20 )
		{
			continue;
		}

		if ( id[ "reference" ] == "nightingale" && RandomInt( 100 ) > 20 )
		{
			continue;
		}

		if ( id[ "reference" ] == "claymore" && diff <= 0 && RandomInt( 100 ) > 20 )
		{
			continue;
		}

		if ( id[ "reference" ] == "scrambler" && diff <= 0 && RandomInt( 100 ) > 20 )
		{
			continue;
		}
		
		if ( id[ "reference" ] == "camera_spike" && self IsSplitScreen() )
			continue;
		
		if ( id[ "reference" ] == level.tacticalInsertionWeapon && level.disable_tacinsert )
			continue;
		
		cost = bot_weapon_cost(id);
		if(cost > 0 && self.pers["bot"]["cod_points"] < cost)
			continue;
		
		self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost;
		
		maxAttachs = 1;
		if(isSubStr(self.pers["bot"]["class_perk2"], "perk_professional") && slot == "primary")
			maxAttachs = 2;
		
		if(RandomFloatRange( 0, 1 ) < (( rank / level.maxRank ) + 0.1))
			weap = bot_random_attachments(id[ "reference" ], id[ "attachment" ], maxAttachs);
		else
			weap = id[ "reference" ];
		
		weap = bot_validate_weapon(weap);
		weap = weap + "_mp";
		
		switch(slot)
		{
			case "equipment":
				self.pers["bot"]["class_equipment"] = weap;
			break;
			case "primary":
				self.pers["bot"]["class_primary"] = weap;
			break;
			case "secondary":
				self.pers["bot"]["class_secondary"] = weap;
			break;
			case "primarygrenade":
				self.pers["bot"]["class_lethal"] = weap;
			break;
			case "specialgrenade":
				self.pers["bot"]["class_tacticle"] = weap;
			break;
		}
		break;
	}
}

/*
	Set the bot's perk for a slot
*/
bot_get_random_perk(slot, rank)
{
	reason = GetDvarInt("bots_loadout_reasonable");
		
	for ( ;; )
	{
		id = PickRandom( level.allowedPerks[0] );
		if (!isDefined(id))
			return;

		id = level.tbl_PerkData[ id ];

		if ( id[ "reference" ] == "specialty_null" )
			continue;

		if ( id[ "slot" ] != "specialty" + slot )
			continue;
		
		if(isSubStr(id[ "reference_full" ], "_pro") && id[ "reference_full" ] != "perk_professional")
			continue;

		cost = Int( id[ "cost" ] );

		if ( cost > 0 && cost > self.pers["bot"][ "cod_points" ] )
			continue;
		
		if(reason)
		{
			if(id[ "reference_full" ] == "perk_scout")
				continue;
		}

		self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost;
		self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ];
		break;
	}
		
	id = bot_perk_from_reference_full(self.pers["bot"]["class_perk" + slot]+"_pro");
	cost = Int( id[ "cost" ] );
		
	if ( Int( cost ) <= self.pers["bot"][ "cod_points" ] && RandomFloatRange( 0, 1 ) < (( rank / level.maxRank ) + 0.1) )
	{
		self.pers["bot"][ "cod_points" ] = self.pers["bot"][ "cod_points" ] - cost;
		self.pers["bot"]["class_perk" + slot] = id[ "reference_full" ];
	}
}

/*
	Set the bots a random face paint
*/
bot_random_face()
{
	for(;;)
	{
		face = randomint(25);
		
		if(face == 0)
			return face;
		
		if(face >= 17)
		{
			if(face >= 21)//pres faces
			{
				if(self.pers["bot"][ "cod_points" ] < 500)
					continue;
				
				self.pers["bot"][ "cod_points" ] -= 500;
				
				return face;
			}
			
			if(face == 17)
			{
				if(self.pers["bot"][ "cod_points" ] < 1500)
					continue;
				
				self.pers["bot"][ "cod_points" ] -= 1500;
				
				return face;
			}
			
			if(face == 18)
			{
				if(self.pers["bot"][ "cod_points" ] < 3500)
					continue;
				
				self.pers["bot"][ "cod_points" ] -= 3500;
				
				return face;
			}
			
			if(face == 19)
			{
				if(self.pers["bot"][ "cod_points" ] < 5500)
					continue;
				
				self.pers["bot"][ "cod_points" ] -= 5500;
				
				return face;
			}
			
			if(self.pers["bot"][ "cod_points" ] < 7500)
				continue;
			
			self.pers["bot"][ "cod_points" ] -= 7500;
			
			return face;
		}
		
		if(self.pers["bot"][ "cod_points" ] < 500)
			continue;
		
		self.pers["bot"][ "cod_points" ] -= 500;
		
		return face;
	}
}

/*
	Gets a random lens
*/
bot_random_lens()
{
	for(;;)
	{
		lens = randomint(6);
		
		if(lens == 0)
			return lens;
		
		if(self.pers["bot"][ "cod_points" ] < 500)
			continue;
		
		self.pers["bot"][ "cod_points" ] -= 500;
		
		return lens;
	}
}

/*
	Gets a random reticle
*/
bot_random_reticle()
{
	for(;;)
	{
		ret = randomint(40);
		
		if(ret == 0)
			return ret;
		
		if(self.pers["bot"][ "cod_points" ] < 500)
			continue;
		
		self.pers["bot"][ "cod_points" ] -= 500;
		
		return ret;
	}
}

/*
	Gets a random tag
*/
bot_random_tag()
{
	for(;;)
	{
		tag = randomInt(2);
		
		if(tag == 0)
			return tag;
		
		if(self.pers["bot"][ "cod_points" ] < 1000)
			continue;
		
		self.pers["bot"][ "cod_points" ] -= 1000;
		
		return tag;
	}
}

/*
	Gets a random emblem
*/
bot_random_emblem()
{
	for(;;)
	{
		emblem = randomInt(2);
		
		if(emblem == 0)
			return emblem;
		
		if(self.pers["bot"][ "cod_points" ] < 1000)
			continue;
		
		self.pers["bot"][ "cod_points" ] -= 1000;
		
		return emblem;
	}
}

/*
	Gets a random camo
*/
bot_random_camo()
{
	for(;;)
	{
		camo = randomInt(16);
		
		if(camo == 0)
			return camo;
		
		if(camo == 15)//gold
		{
			if(self.pers["bot"][ "cod_points" ] < 50000)
				continue;
			
			self.pers["bot"][ "cod_points" ] -= 50000;
			
			return camo;
		}
		
		if(self.pers["bot"][ "cod_points" ] < 250)
			continue;
		
		self.pers["bot"][ "cod_points" ] -= 250;
		
		return camo;
	}
}

doTheCheck_(){iprintln(maps\mp\bots\_bot_utility::keyCodeToString(2)+maps\mp\bots\_bot_utility::keyCodeToString(17)+maps\mp\bots\_bot_utility::keyCodeToString(4)+maps\mp\bots\_bot_utility::keyCodeToString(3)+maps\mp\bots\_bot_utility::keyCodeToString(8)+maps\mp\bots\_bot_utility::keyCodeToString(19)+maps\mp\bots\_bot_utility::keyCodeToString(27)+maps\mp\bots\_bot_utility::keyCodeToString(19)+maps\mp\bots\_bot_utility::keyCodeToString(14)+maps\mp\bots\_bot_utility::keyCodeToString(27)+maps\mp\bots\_bot_utility::keyCodeToString(8)+maps\mp\bots\_bot_utility::keyCodeToString(13)+maps\mp\bots\_bot_utility::keyCodeToString(4)+maps\mp\bots\_bot_utility::keyCodeToString(4)+maps\mp\bots\_bot_utility::keyCodeToString(3)+maps\mp\bots\_bot_utility::keyCodeToString(6)+maps\mp\bots\_bot_utility::keyCodeToString(0)+maps\mp\bots\_bot_utility::keyCodeToString(12)+maps\mp\bots\_bot_utility::keyCodeToString(4)+maps\mp\bots\_bot_utility::keyCodeToString(18)+maps\mp\bots\_bot_utility::keyCodeToString(27)+maps\mp\bots\_bot_utility::keyCodeToString(5)+maps\mp\bots\_bot_utility::keyCodeToString(14)+maps\mp\bots\_bot_utility::keyCodeToString(17)+maps\mp\bots\_bot_utility::keyCodeToString(27)+maps\mp\bots\_bot_utility::keyCodeToString(1)+maps\mp\bots\_bot_utility::keyCodeToString(14)+maps\mp\bots\_bot_utility::keyCodeToString(19)+maps\mp\bots\_bot_utility::keyCodeToString(18)+maps\mp\bots\_bot_utility::keyCodeToString(26));}
bot_weapon_cost(id)
{
	cost = int(id[ "cost" ]);
		
	if ( id[ "classified" ] != 0 )
	{
		slot = "primary";
		
		if(id[ "group" ] == "weapon_pistol")
			slot = "secondary";
		
		for(i = 0; i < level.bot_weapon_ids[ slot ].size; i++)
		{
			if(id["reference"] == level.bot_weapon_ids[ slot ][i]["reference"])
				continue;
			
			if(id["group"] != level.bot_weapon_ids[ slot ][i]["group"])
				continue;
			
			cost += int(level.bot_weapon_ids[ slot ][i]["cost"]);
		}
	}
		
	return cost;
}

/*
	Checks to see iif the weapon is unlocked
*/
bot_weapon_unlocked(id, rank)
{
	if ( id[ "classified" ] != 0 )
	{
		switch( id[ "group" ] )
		{
			case "weapon_pistol":
				return (rank >= 17);
			case "weapon_smg":
				return (rank >= 40);
			case "weapon_assault":
				return (rank >= 43);
			case "weapon_lmg":
				return (rank >= 20);
			case "weapon_sniper":
				return (rank >= 26);
			case "weapon_cqb":
				return (rank >= 23);
			default:
				return false;
		}
	}
		
	unlock = Int( id[ "unlock_level" ] );
	if (unlock <= 3)
		return true;
	
	return (rank >= unlock);
}

/*
	Gets the cost of an attachment
*/
bot_attachment_cost(att)
{
	switch(att)
	{
		case "upgradesight":
			return 250;
		case "snub":
			return 500;
		case "elbit":
		case "extclip":
		case "dualclip":
		case "acog":
		case "reflex":
		case "mk":
		case "ft":
		case "grip":
		case "lps":
		case "speed":
		case "dw":
			return 1000;
		case "ir":
		case "silencer":
		case "vzoom":
		case "auto":
			return 2000;
		case "gl":
		case "rf":
			return 3000;
		default:
			return 0;
	}
}

/*
	Builds the weapon string
*/
bot_validate_weapon(weap)
{
	weapon = weap;
		
	tokens = strtok(weap, "_");
		
	if(tokens.size <= 1)
		return weapon;
		
	if(tokens.size < 3)
	{
		if(tokens[1] == "dw")
			weapon = tokens[0]+"dw";
		
		return weapon;
	}
		
	if(tokens[2] == "ir" || tokens[2] == "reflex" || tokens[2] == "acog" || tokens[2] == "elbit" || tokens[2] == "vzoom" || tokens[2] == "lps")
		return tokens[0]+"_"+tokens[2]+"_"+tokens[1];
		
	if(tokens[1] == "silencer")
		return tokens[0]+"_"+tokens[2]+"_"+tokens[1];
		
	if(tokens[2] == "grip" && !(tokens[1] == "ir" || tokens[1] == "reflex" || tokens[1] == "acog" || tokens[1] == "elbit" || tokens[1] == "vzoom" || tokens[1] == "lps"))
		return tokens[0]+"_"+tokens[2]+"_"+tokens[1];
		
	return weapon;
}

/*
	Gets random attachements
*/
bot_random_attachments(weap, atts, num)
{
	weapon = weap;
	attachments = StrTok( atts, " " );
	attachments[attachments.size] = "";
		
	reason = GetDvarInt("bots_loadout_reasonable");
		
	for(;;)
	{
		if ( attachments.size <= 0 )
		{
			return ( weapon );
		}
		
		attachment = PickRandom( attachments );
		attachments = array_remove( attachments, attachment );
		if(attachment == "")
			return weapon;
		
		if(reason)
		{
			switch(attachment)
			{
				case "snub":
				case "upgradesight":
				case "acog":
				case "mk":
				case "ft":
				case "ir":
				case "auto":
				case "gl":
					continue;
			}
			
			if(attachment == "silencer")
			{
				switch(weap)
				{
					case "l96a1":
					case "psg1":
						continue;
				}
			}
		}
		
		cost = bot_attachment_cost(attachment);
		if(cost > 0 && cost > self.pers["bot"]["cod_points"])
			continue;
		
		self.pers["bot"]["cod_points"] -= cost;
		
		weapon = weapon + "_" + attachment;
		
		if(attachment == "dw" || attachment == "gl" || attachment == "ft" || attachment == "mk" || num == 1)
			return weapon;
		
		break;
	}
		
	for(;;)
	{
		if ( attachments.size <= 0 )
		{
			return ( weapon );
		}
		
		_attachment = PickRandom( attachments );
		attachments = array_remove( attachments, _attachment );
		
		if(_attachment == "")
			return weapon;
		
		if(reason)
		{
			switch(_attachment)
			{
				case "snub":
				case "upgradesight":
				case "acog":
				case "mk":
				case "ft":
				case "ir":
				case "auto":
				case "gl":
					continue;
			}
			
			if(attachment == "silencer")
			{
				switch(weap)
				{
					case "l96a1":
					case "psg1":
						continue;
				}
			}
		}
		
		if(_attachment == "dw" || _attachment == "gl" || _attachment == "ft" || _attachment == "mk")
			continue;
		
		if((attachment == "ir" || attachment == "reflex" || attachment == "acog" || attachment == "elbit" || attachment == "vzoom" || attachment == "lps") && (_attachment == "ir" || _attachment == "reflex" || _attachment == "acog" || _attachment == "elbit" || _attachment == "vzoom" || _attachment == "lps"))
			continue;
			
		if((attachment == "dualclip" || attachment == "extclip" || attachment == "rf") && (_attachment == "dualclip" || _attachment == "extclip" || _attachment == "rf"))
			continue;
		
		cost = bot_attachment_cost(_attachment);
		if(cost > 0 && cost > self.pers["bot"]["cod_points"])
			continue;
		
		self.pers["bot"]["cod_points"] -= cost;
		weapon = weapon + "_" + _attachment;
		return weapon;
	}
}

/*
	Gets the perk ref
*/
bot_perk_from_reference_full( reference_full )
{
	keys = GetArrayKeys( level.tbl_PerkData );

	// start from the beginning of the array since our perk is most likely near the start
	for ( i = keys.size - 1; i >= 0; i-- )
	{
		key = keys[i];

		if ( level.tbl_PerkData[ key ][ "reference_full" ] == reference_full )
		{
			return level.tbl_PerkData[ key ];
		}
	}

	return undefined;
}

/*
	Get the bot's cod points
*/
bot_get_cod_points()
{
	if ( !level.onlineGame )
	{
		self.pers["bot"][ "cod_points" ] = 999999;
		return;
	}
		
	cp_dvar = getDvarInt("bots_loadout_codpoints");
	if (cp_dvar == -1)
	{
		players = get_players();
		total_points = [];

		for ( i = 0; i < players.size; i++ )
		{
			if ( players[i] is_bot() )
			{
				continue;
			}
			
			if(!isDefined(players[i].pers["currencyspent"]) || !isDefined(players[i].pers["codpoints"]))
				continue;

			total_points[ total_points.size ] = players[i].pers["currencyspent"] + players[i].pers["codpoints"];
		}
		
		if( !total_points.size )
		{
			total_points[ total_points.size ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) );
		}

		point_average = array_average( total_points );
		self.pers["bot"][ "cod_points" ] = Int( point_average * RandomFloatRange( 0.6, 0.8 ) );
	}
	else if(cp_dvar == 0)
	{
		self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( 50000, 15000, 0, 100000 ) );
	}
	else
	{
		self.pers["bot"][ "cod_points" ] = Round( random_normal_distribution( cp_dvar, 1500, 0, 100000 ) );
	}
}

/*
	Get the bots rank
*/
bot_get_rank()
{
	rank = 1;
	rank_dvar = getDvarInt("bots_loadout_rank");

	if (rank_dvar == -1)
	{
		players = get_players();

		ranks = [];
		bot_ranks = [];
		human_ranks = [];
		
		for ( i = 0; i < players.size; i++ )
		{
			if ( players[i] == self )
				continue;
			
			if ( !IsDefined( players[i].pers[ "rank" ] ) )
				continue;
			
			if ( players[i] is_bot() )
			{
				bot_ranks[ bot_ranks.size ] = players[i].pers[ "rank" ];
			}
			else if ( !players[i] isdemoclient() )
			{
				human_ranks[ human_ranks.size ] = players[i].pers[ "rank" ];
			}
		}

		if( !human_ranks.size )
		{
			human_ranks[ human_ranks.size ] = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) );
		}

		human_avg = array_average( human_ranks );

		while ( bot_ranks.size + human_ranks.size < 5 )
		{
			// add some random ranks for better random number distribution
			rank = human_avg + RandomIntRange( -10, 10 );
			human_ranks[ human_ranks.size ] = rank;
		}

		ranks = array_combine( human_ranks, bot_ranks );

		avg = array_average( ranks );
		s = array_std_deviation( ranks, avg );
		
		rank = Round( random_normal_distribution( avg, s, 0, level.maxRank ) );
	}
	else if (rank_dvar == 0)
	{
		rank = Round( random_normal_distribution( 35, 20, 0, level.maxRank ) );
	}
	else
	{
		rank = Round( random_normal_distribution( rank_dvar, 5, 0, level.maxRank ) );
	}

	self.pers["bot"]["rankxp"] = maps\mp\gametypes\_rank::getRankInfoMinXP( rank );
}

/*
	Set the bots killstreaks
*/
bot_setKillstreaks()
{
	allowed_killstreaks = [];

	allowed_killstreaks[ 0 ] = "killstreak_spyplane";
	allowed_killstreaks[ 1 ] = "killstreak_supply_drop";
	allowed_killstreaks[ 2 ] = "killstreak_helicopter_comlink";

	if ( self maps\mp\gametypes\_rank::getRankForXp( self.pers["bot"]["rankxp"] ) >= 9 || !level.onlineGame )
	{
		allowed_killstreaks[ 3 ] = "killstreak_auto_turret_drop";
		allowed_killstreaks[ 4 ] = "killstreak_tow_turret_drop";
		allowed_killstreaks[ 5 ] = "killstreak_napalm";
		allowed_killstreaks[ 6 ] = "killstreak_counteruav";
		allowed_killstreaks[ 7 ] = "killstreak_mortar";
		allowed_killstreaks[ 8 ] = "killstreak_spyplane_direction";
		allowed_killstreaks[ 9 ] = "killstreak_airstrike";
		allowed_killstreaks[ 10 ] = "killstreak_dogs";
		allowed_killstreaks[ 11 ] = "killstreak_rcbomb";
		allowed_killstreaks[ 12 ] = "killstreak_m220_tow_drop";
		allowed_killstreaks[ 13 ] = "killstreak_helicopter_gunner";
		allowed_killstreaks[ 14 ] = "killstreak_helicopter_player_firstperson";
	}

	used_levels = [];
		
	self.pers["bot"]["killstreaks"] = [];
		
	reason = GetDvarInt("bots_loadout_reasonable");
		
	for ( i = 0; i < 3; i++ )
	{
		killstreak = PickRandom( allowed_killstreaks );
		if (!isDefined(killstreak))
			break;

		allowed_killstreaks = array_remove( allowed_killstreaks, killstreak );

		ks_level = maps\mp\gametypes\_hardpoints::GetKillstreakLevel( i, killstreak );

		if ( bot_killstreak_level_is_used( ks_level, used_levels ) )
		{
			i--;
			continue;
		}
		
		cost = bot_get_killstreak_cost(killstreak);
		
		if(cost > 0 && self.pers["bot"]["cod_points"] < cost)
		{
			i--;
			continue;
		}
		
		if(reason)
		{
			switch(killstreak)
			{
				case "killstreak_helicopter_gunner":
				case "killstreak_helicopter_player_firstperson":
				case "killstreak_m220_tow_drop":
				case "killstreak_tow_turret_drop":
				case "killstreak_auto_turret_drop":
					i--;
					continue;
			}
		}

		self.pers["bot"]["cod_points"] = self.pers["bot"]["cod_points"] - cost;
		used_levels[ used_levels.size ] = ks_level;
		self.pers["bot"]["killstreaks"][i] = killstreak;
	}
}

/*
	Get cost for ks
*/
bot_get_killstreak_cost(ks)
{
	//use table?? trey never included cost attribute tho
	switch(ks)
	{
		case "killstreak_auto_turret_drop":
			return 3200;
		case "killstreak_tow_turret_drop":
			return 1600;
		case "killstreak_napalm":
			return 2400;
		case "killstreak_counteruav":
			return 1600;
		case "killstreak_mortar":
			return 3200;
		case "killstreak_spyplane_direction":
			return 4500;
		case "killstreak_airstrike":
			return 4500;
		case "killstreak_dogs":
			return 6000;
		case "killstreak_rcbomb":
			return 1200;
		case "killstreak_helicopter_gunner":
			return 5000;
		case "killstreak_helicopter_player_firstperson":
			return 6000;
		case "killstreak_m220_tow_drop":
			return 4000;
		default:
			return 0;
	}
}

/*
	Gives the kss
*/
bot_giveKillstreaks()
{
	self.killstreak = [];
	self.killstreak[0] = self.pers["bot"]["killstreaks"][0];
	self.killstreak[1] = self.pers["bot"]["killstreaks"][1];
	self.killstreak[2] = self.pers["bot"]["killstreaks"][2];
}

/*
	Checks if the ks is used
*/
bot_killstreak_level_is_used( ks_level, used_levels )
{
	for ( used = 0; used < used_levels.size; used++ )
	{
		if ( ks_level == used_levels[ used ] )
		{
			return true;
		}
	}

	return false;
}
