// This script contains functionality to allow bots to choose primary weapons
this.Name = "SelectWeapons";
this.Parent = "Limbo";	
this.Debug = false;
this.AlwaysRecieveEvents = true;

//this.LimitToClass(CLASS.SOLDIER, CLASS.COVERTOPS);

// shared weapon counters
this.UsingWeapons = {};
this.UsingWeapons[ TEAM.ALLIES ] = {};
this.UsingWeapons[ TEAM.AXIS ] = {};

this.Initialize = function()
{
	if ( Map && (Map.DontSelectWeapons || Map.PanzerMap) ) {
		this.Disable = true;
		return;
	}

	if (!MinPlayersForMortar) {
		global MinPlayersForMortar = ConfigGet("HeavyWeapons","MinPlayersForMortar", -1);
		global MinPlayersForMobileMG = ConfigGet("HeavyWeapons","MinPlayersForMobileMG", -1);
	}

	this.EXCLUDE_MORTAR_AND_MG42 = {};
	this.EXCLUDE_MORTAR_AND_MG42 [WEAPON.MOBILE_MG42] = true;
	this.EXCLUDE_MORTAR_AND_MG42 [WEAPON.MORTAR] = true;

	this.EXCLUDE_SNIPE = {};
	this.EXCLUDE_SNIPE [WEAPON.GARAND] = true;
	this.EXCLUDE_SNIPE [WEAPON.K43] = true;
	this.EXCLUDE_SNIPE [WEAPON.PROTO] = true;
};

// Count the number of users for a particular weapon id
this.NumWeaponUsers = function(weaponId)
{
	num = 0;
	deleted = null;
	teamWeapons = this.UsingWeapons[ this.Bot.GetTeam() ];
	foreach ( bot and weapon in teamWeapons)
	{
		if (weapon == weaponId){
			if (!bot.Name) {
				// bot disconnected
				if (!deleted){ deleted = table(); }
				deleted[tableCount(deleted)] = bot;
			}else{
				num += 1;
			}
		}
	}
	if (deleted) {
		foreach ( bot in deleted) {
			teamWeapons[bot] = null;
		}
	}
	return num;
};

this.GetPriority = function()
{
	this.Priority = 1;
	block(0);
};

this.Update = function()
{
	if ( this.Debug ) {
		foreach ( id and weap in WEAPON ) {
			if ( this.Bot.HasWeapon(weap) ) {
				this.Bot.Say("have weapon " + id);
			}
		}
	}

	if(!this.Bot.ClassPrimaryWeaponChoice){
		print("ClassPrimaryWeaponChoice not defined for bot ", this.Bot.Name);
		block(0);
	}

	// This is needed in order to finish the goal. Without it, the goal will continue to have Update called on it.
	while(1)
	{
		myTeam = this.Bot.GetTeam();

		// this.Bot.HasWeapon cannot be used, because it always returns false !!!
		// cs: this.Bot.HasWeapon should be fixed now ...
		lastWeapon = this.UsingWeapons[myTeam][this.Bot];

		switch (this.Bot.GetClass())
		{
			case CLASS.SOLDIER:
			{
				// count how many goals are available for each weapon type
				goals_mg42 = Util.GoalTable("MOBILEMG42.*", myTeam);
				goals_mortar = Util.GoalTable("MOBILEMORTAR.*", myTeam);
				numMg42Goals = tableCount(goals_mg42);
				numMortarGoals = tableCount(goals_mortar);

				// count how many other bots have these weapons
				numMg42Users = 9;
				if(numMg42Goals > 0){
					numMg42Users = this.NumWeaponUsers(WEAPON.MOBILE_MG42);
				}
				numMortarUsers = 9;
				if(numMortarGoals > 0){
					numMortarUsers = this.NumWeaponUsers(WEAPON.MORTAR);
				}
				if(this.Debug)
				{
					print(this.Bot.Name, ":" ,Util.TeamName(myTeam), ": # Mg42 Users:",numMg42Users,"/",numMg42Goals);
					print(this.Bot.Name, ":" ,Util.TeamName(myTeam), ": # Mortar Users:",numMortarUsers,"/",numMortarGoals);
				}

				if(lastWeapon != WEAPON.MOBILE_MG42) { numMg42Users += 1; }
				if(lastWeapon != WEAPON.MORTAR) { numMortarUsers += 1; }

				if(numMortarUsers <= numMortarGoals && Server.NumPlayers >= MinPlayersForMortar * numMortarUsers)
				{
					newWeapon = WEAPON.MORTAR;
				}
				else if(numMg42Users <= numMg42Goals && Server.NumPlayers >= MinPlayersForMobileMG * numMg42Users)
				{
					newWeapon = WEAPON.MOBILE_MG42;

					//enable mid-clip reload for skilled soldier
					modName = GetModName();
					if (modName == "noquarter" || modName == "nitmod")
					{
						skills = {};
						this.Bot.GetSkills(skills);
						if (skills[SKILL.HEAVY_WEAPONS] > 4) {
							wpn = this.Bot.GetWeapon(WEAPON.MOBILE_MG42);
							if (wpn) {
								wpn.PrimaryFire.IgnoreReload = false;
							}
						}
					}
				}
				else
				{
					// pick a new weapon other than mg42 and mortar
					newWeapon = this.Bot.ClassPrimaryWeaponChoice(this.EXCLUDE_MORTAR_AND_MG42);
				}
			}
			case CLASS.COVERTOPS:
			{
				// count how many goals are available
				if (Util.IsSnipeMap) {
					numSnipeGoals = 99;
				}
				else
				{
					goals_snipe = {};
					GetGoals(goals_snipe,myTeam,"SNIPE_.*");
					numSnipeGoals = tableCount(goals_snipe);
				}

				if (numSnipeGoals > 0)
				{
					tbl = Util.TeamSniperWeapons[ Util.TeamName(myTeam) ];
					newWeapon = Util.GetRandomTableValue(tbl);
				}
				else
				{
					// pick a new weapon other than GARAND and K43
					newWeapon = this.Bot.ClassPrimaryWeaponChoice(this.EXCLUDE_SNIPE);
				}
			}
			default:
			{
				//random available weapon
				newWeapon = this.Bot.ClassPrimaryWeaponChoice(null);
			}
		}

		if (newWeapon)
		{
			//WeaponTable.SetWeaponAvailability can be called anytime from triggers,
			//ChangePrimaryWeapon will switch to another weapon if current weapon availability is false
			this.Bot.ChangePrimaryWeapon(newWeapon);
			this.UsingWeapons[myTeam][this.Bot] = newWeapon;

			if(this.Debug && newWeapon!=lastWeapon)
			{
				this.Bot.SayTeam("Changing to ", Util.WeaponName(newWeapon));
				print(this.Bot.Name, ":" ,"Chose New Weapon:",Util.WeaponName(newWeapon));
			}
		}

		sleep(this.Bot.GetReinforceTime() + 1);
	}
};

this.Events[EVENT.CHANGETEAM] = function(newTeam)
{
	if (newTeam==TEAM.AXIS){ oldTeam=TEAM.ALLIES; } else { oldTeam=TEAM.AXIS; }
	weapon = this.UsingWeapons[oldTeam][this.Bot];
	if (weapon) {
		this.UsingWeapons[oldTeam][this.Bot] = null;
		this.UsingWeapons[newTeam][this.Bot] = weapon;
	}
};

Commands["minformortar"] =
{
	Func = function( _params )
	{
		minformortar = ToInt(_params[0], -1);
		ConfigSet("HeavyWeapons","MinPlayersForMortar", minformortar);
		global MinPlayersForMortar = minformortar;
		print("MinPlayersForMortar set to", minformortar);
	},

	Help =
	{
		"set the minimum number of players playing in order for bots to choose the mobile mortar",
	},
};

Commands["minformobilemg"] =
{
	Func = function( _params )
	{
		minformobilemg = ToInt(_params[0], -1);
		ConfigSet("HeavyWeapons","MinPlayersForMobileMG", minformobilemg);
		global MinPlayersForMobileMG = minformobilemg;
		print("MinPlayersForMobileMG set to", minformobilemg);
	},

	Help =
	{
		"set the minimum number of players playing in order for bots to choose the mobile mg42",
	},
};
