// This script contains functionality to allow bots to camp on a given position. It can be restricted to specific weapons (panzer, flamethrower, sniper).
this.Name = "CAMP";
this.Parent = "HighLevel";
this.SkipGetPriorityWhenActive = true;
this.Debug = false;
this.query = { 0xa9ef3654 /* CAMP */, 0x4fed19c1 /* DEFEND */, 0x4595b8fd /* ATTACK */, 0xe8fbadc0 /* SNIPE */ };

this.GetPriority = function()
{
	Util.GetPriority(this, this.query);
};

this.Enter = function()
{
	if(!this.MarkInProgress()) { this.Finished(); }
};

this.Exit = function()
{
	this.Bot.ReleaseButton(BTN.CROUCH, BTN.PRONE);

	// restore combat movement restrictions
	if (this.CombatMovementDisabled) {
		this.Bot.DisableCombatMovement = false;
		this.CombatMovementDisabled = false;
	}

	// restore weapon desirability
	wpn = this.DesirableWeapon;
	if (wpn) {
		this.DesirableWeapon = null;
		//command /bot reload_weapons causes error "getdot failed on null user type"
		wpn.PrimaryFire.DefaultDesirability = this.OldDesirability;
		this.OldDesirability = null;
	}
};

this.Update = function()
{
	Util.RouteTo(this);

	UsingWeapon = 0;
	IsSniper = null;

	if ( this.MapGoal.Weapons )
	{
		if (tableCount(this.MapGoal.Weapons) > 0)
		{
			UsingWeapon = this.Bot.HasAnyWeapon(this.MapGoal.Weapons, { CheckCharged=false, CheckAmmo=false });
			IsSniper = Util.IndexedSniperWeapons[UsingWeapon];
		}
	}
	else if (this.Debug)
	{
		print(this.MapGoal.GetName() + " has no Weapons Table");
	}

	if(this.Debug)
	{
		print("camp goal update", Util.WeaponName(UsingWeapon), UsingWeapon, IsSniper);
	}

	if (this.MapGoal.DisableCM > 0 && !this.Bot.DisableCombatMovement)
	{
		this.CombatMovementDisabled = true;
		this.Bot.DisableCombatMovement = true;
	}

	if (!this.DesirableWeapon)
	{
		wpn = UsingWeapon;
		if (!wpn) {
			wpn = ETUtil.GetBotPrimaryWeapon(this.Bot);
		}
		// AddWeaponRequest cannot be used because it ignores ammo and charge
		if (wpn) {
			weap = this.Bot.GetWeapon(wpn);
			if (weap) {
				this.OldDesirability = weap.PrimaryFire.DefaultDesirability;
				this.DesirableWeapon = weap;
				if (UsingWeapon) {
					weap.PrimaryFire.DefaultDesirability = 0.9;
				} else if(this.OldDesirability > 0) {
					weap.PrimaryFire.DefaultDesirability = this.OldDesirability + 0.15;
				}
			}
		}
	}


	peektime = 0;
	CampTime = RandFloat(this.MapGoal.MinCampTime, this.MapGoal.MaxCampTime);
	for(timeout = 0; timeout < CampTime; timeout += 1)
	{
		if ( UsingWeapon && !this.Bot.HasAmmo(UsingWeapon) )
		{
			if(this.Debug)
			{
				print("camp goal has no ammo for", Util.WeaponName(UsingWeapon));
			}
			this.BlackboardDelay(20);
			this.Finished();
		}

		switch (this.MapGoal.Stance)
		{
			case "crouch":
			{
				this.Bot.HoldButton(BTN.CROUCH, 1.1);
			}
			case "prone":
			{
				this.Bot.HoldButton(BTN.PRONE, 1.1);
			}
			case "peek":
			{
				if ( timeout % RandInt(2,4) == 0 ) { // stand
					if ( peektime == 0 ) {
						peektime = timeout + this.Bot.ReactionTime + 1;
					}
				}
				else if ( timeout >= peektime ) { // hide
					peektime = 0;
					this.Bot.HoldButton(BTN.CROUCH, RandInt(1,3));
				}
			}
		}

		if ( IsSniper && this.Bot.GetCurrentWeapon()==UsingWeapon )
		{
			this.Bot.HoldButton(BTN.AIM,1.1);
		}

		this.AddAimRequest(Priority.Low, "facing", Util.GetRandomTableValue(this.MapGoal.AimVectors));

		sleep(1);
	}

	// don't choose the same camp spot
	this.BlackboardDelay(5);
	this.Finished();
};
