// This script contains functionality to allow bots respond to miscelaneous events

this.Name = "VoiceChat";
this.Parent = "LowLevel";
this.AutoAdd = true;
this.AlwaysRecieveEvents = true;

Util.TeamBotChangeClassExecuted = 0;

this.Initialize = function()
{
	// the default frequency based on a 1 to 10 scale. setting to 0 will disable
	this.Frequency = 4; // 40% chance to respond

	// allow or disallow bots to respond to other bots
	this.OnlyRespondToHumans = false;

	// optionally scale the frequency based on number of bots
	// the frequency rate will be reduced by this number for every bot
	// useful for servers running a lot of bots to reduce noise
	this.FrequencyReductionPerBot = 0.1;

	// optionally fine tune frequency rates per response type. setting to 0 will disable
	this.TEAMTHANKS_SAYWELCOME 	= this.Frequency;
	this.REVIVED_SAYTHANKS		= this.Frequency;
	this.HEALED_SAYTHANKS		= this.Frequency;
	this.AMMO_SAYTHANKS		= this.Frequency;
	this.TEAMKILL_SAYSORRY		= this.Frequency;
	this.TEAMKILL_SAYOOPS		= this.Frequency;
	this.REVENGE_CHEER		= this.Frequency;
	this.KNIFEKILL_CHEER		= this.Frequency;
	this.KNIFEDEATH_GREATSHOT	= this.Frequency;
	this.KNIFEDEATH_NEGATIVE	= this.Frequency;
	this.TEAMPAIN_HOLDFIRE		= this.Frequency;
	this.GOODBYE_SAYGOODBYE		= this.Frequency;
	this.HELLO_SAYHELLO		= this.Frequency;
	this.NEEDENG_SAYENG		= this.Frequency;
	this.NEEDMED_SAYMED		= this.Frequency * 0.25;
	this.NEEDOPS_SAYOPS		= this.Frequency;
	this.BUILD_SAYBUILD		= this.Frequency;
	this.PLANT_SAYCOVER		= this.Frequency;
	this.DEFEND_SAYDEFEND		= this.Frequency * 0.5;
	this.ATTACK_SAYATTACK		= this.Frequency * 0.5;
};

this.Randomize = function(frequency, source)
{
	if ( this.OnlyRespondToHumans && !Util.IsHuman(source) ) {
		return false;
	}

	if ( !frequency ) { frequency = this.Frequency; }

	// scale it based on bot count
	frequency = frequency - ( tableCount(BotTable) * this.FrequencyReductionPerBot );
	if ( frequency < 1 && this.Frequency > 0 ) { frequency = 1; }

	if ( RandFloat(0, 10) < frequency  )
	{
		sleep(RandFloat(0.5, 1.0));
		if (!this.Bot) { exit(); }
		return true;
	}

	return false;
};

this.GetPriority = function()
{
	// special case for some engineer goals. note: disabled if only response is for humans
	// signals are sent from goal_build and goal_plant once they start the goal
	t = block(this.Bot.Name + "_construct", this.Bot.Name + "_plant", this.Bot.Name + "_defend", this.Bot.Name + "_attack");

	if ( t == this.Bot.Name + "_construct"
		&& this.Randomize(this.BUILD_SAYBUILD, true) == true )
	{
		this.Bot.SayVoice(VOICE.CONST_COMMENCING);
	}
	else if ( t == this.Bot.Name + "_plant"
		&& this.Randomize(this.PLANT_SAYCOVER, true) == true )
	{
		this.Bot.SayVoice(VOICE.COVER_ME);
	}
	else if ( t == this.Bot.Name + "_defend" // from goal_rolemanager.gm
		&& this.Randomize(this.DEFEND_SAYDEFEND, true) == true )
	{
		this.Bot.SayVoice(VOICE.ON_DEFENSE);
	}
	else if ( t == this.Bot.Name + "_attack" // from goal_rolemanager.gm
		&& this.Randomize(this.ATTACK_SAYATTACK, true) == true )
	{
		this.Bot.SayVoice(VOICE.ON_OFFENSE);
	}

	// force a delay
	sleep(10);
};

this.Events[EVENT.TEAM_VOICE] = function(source, id)
{
	if (!this.Bot) { return; }

	cls = this.Bot.GetClass();

	switch(id)
	{
		case VOICE.THANKS:
		{
			if ( cls == CLASS.MEDIC || cls == CLASS.FIELDOPS
				&& this.Randomize(this.TEAMTHANKS_SAYWELCOME, source) == true )
			{
				pos = GetEntPosition(source);
				if ( pos && this.Bot.DistanceTo( pos ) < 80 ) {
					this.Bot.SayVoice(VOICE.WELCOME);
				}
			}
			return;
		}
		case VOICE.NEED_ENGINEER:
		{
			if ( cls == CLASS.ENGINEER && this.Randomize(this.NEEDENG_SAYENG, source) == true )
			{
				this.Bot.SayVoice(VOICE.IMA_ENGINEER);
			}
			return;
		}
		case VOICE.NEED_MEDIC:
		{
			if ( cls == CLASS.MEDIC && this.Randomize(this.NEEDMED_SAYMED, source) == true )
			{
				this.Bot.SayVoice(VOICE.IMA_MEDIC);
			}
			return;
		}
		case VOICE.NEED_OPS:
		{
			if ( cls == CLASS.COVERTOPS && this.Randomize(this.NEEDOPS_SAYOPS, source) == true )
			{
				this.Bot.SayVoice(VOICE.IMA_COVERTOPS);
			}
			return;
		}
	}
};

this.Events[EVENT.TEAM_CHAT_MSG] = function(source, id)
{
	sleep(RandFloat(0.01, 1.00));
	
	if (!this.Bot) { return; }

	//print(this.Bot.Name, " can be changed = ", !Util.TeamBotChangeClassExecuted);
	if(Util.TeamBotChangeClassExecuted == 1)
	{
		sleep(1.1);
		Util.TeamBotChangeClassExecuted = 0;
		return;
	}
	else
	{
		cls = this.Bot.GetClass();

		if (id.Length() == 7)
		{
			botChanged = 0;
			switch(id.Left(3))
			{
				case "sol":					
				{
					currClass = CLASS.SOLDIER;
				}
				case "med":
				{
					currClass = CLASS.MEDIC;
				}
				case "eng":
				{
					currClass = CLASS.ENGINEER;
				}
				case "fop":
				{
					currClass = CLASS.FIELDOPS;
				}
				case "cov":
				{
					currClass = CLASS.COVERTOPS;
				}
			}
			
			switch(id.Right(3))
			{
				case "sol":					
				{
					newClass = CLASS.SOLDIER;
				}
				case "med":
				{
					newClass = CLASS.MEDIC;
				}
				case "eng":
				{
					newClass = CLASS.ENGINEER;
				}
				case "fop":
				{
					newClass = CLASS.FIELDOPS;
				}
				case "cov":
				{
					newClass = CLASS.COVERTOPS;
				}
			}
			
			if (cls == currClass)
			{
				print("****** CHANGING BOT CLASS FOR ", this.Bot.Name, " ******");
				Util.TeamBotChangeClassExecuted = 1;
				this.Bot.ChangeClass(newClass);
				//this.Bot.ExecCommand("kill");
			}
		}
	}
};

this.Events[EVENT.REVIVED] = function(whoDoneIt)
{
	if ( this.Bot && whoDoneIt != this.Bot.GetGameEntity() && this.Bot.IsAllied(whoDoneIt)
		&& this.Randomize(this.REVIVED_SAYTHANKS, whoDoneIt ) == true )
	{
		this.Bot.SayVoice(VOICE.THANKS);
	}
};

this.Events[EVENT.HEALED] = function(whoDoneIt)
{
	if ( this.Bot && whoDoneIt != this.Bot.GetGameEntity() && this.Bot.IsAllied(whoDoneIt)
		&& this.Randomize(this.HEALED_SAYTHANKS, whoDoneIt) == true )
	{
		this.Bot.SayVoice(VOICE.THANKS);
	}
};

this.Events[EVENT.AMMO_RECIEVED] = function(whoDoneIt)
{
	if ( this.Bot && whoDoneIt != this.Bot.GetGameEntity()
		&& this.Randomize(this.AMMO_SAYTHANKS, whoDoneIt) == true )
	{
		this.Bot.SayVoice(VOICE.THANKS);
	}
};

this.Events[EVENT.KILLEDSOMEONE] = function(victim, mod)
{
	if (!this.Bot) { return; }

	if ( this.Bot.KillingForRevive == true ) { return; }

	if ( this.Bot.IsAllied( victim ) && victim != this.Bot.GetGameEntity() )
	{
		if( this.Randomize(this.TEAMKILL_SAYSORRY, victim) == true )
			{ this.Bot.SayVoice( VOICE.SORRY ); }
		else if ( this.Randomize(this.TEAMKILL_SAYOOPS, victim) == true )
			{ this.Bot.SayVoice( VOICE.OOPS ); }

		return;
	}

	// cheer the revenge
	if ( this.LastKiller && this.LastKiller == victim )
	{
		this.LastKiller = null; // always clear this

		if ( this.Randomize(this.REVENGE_CHEER, victim) == true )
		{
			this.Bot.SayVoice( VOICE.G_CHEER );
		}

		return;
	}

	if ( mod == "MOD_KNIFE_STEALTH" || mod == "MOD_KNIFE" || mod == "MOD_KNIFE_THROWN" )
	{
		if ( this.Randomize(this.KNIFEKILL_CHEER, victim) == true )
		{
			this.Bot.SayVoice( VOICE.G_CHEER );
		}

		return;
	}
};

this.Events[EVENT.DEATH] = function(attacker, mod)
{
	if ( !this.Bot || GetGameIdFromEntity(attacker) > 63 )
		{ return;}

	if ( !this.Bot.IsAllied( attacker ) )
	{
		this.LastKiller = attacker;

		if ( (mod == "MOD_KNIFE_STEALTH" || mod == "MOD_KNIFE" || mod == "MOD_KNIFE_THROWN") )
		{
			if ( this.Randomize(this.KNIFEDEATH_GREATSHOT, attacker) == true )
				{ this.Bot.SayVoice( VOICE.G_GREATSHOT ); }
			else if ( this.Randomize(this.KNIFEDEATH_NEGATIVE, attacker) == true )
				{ this.Bot.SayVoice( VOICE.G_NEGATIVE ); }

			return;
		}
	}
};

this.Events[EVENT.FEEL_PAIN] = function(Inflictor, PreviousHealth, CurrentHealth)
{
	if ( !this.Bot || GetGameIdFromEntity(Inflictor) > 63 )
		{ return;}

	if ( !this.responding_to_teamdamage && this.Bot.IsAllied(Inflictor)
		&& Inflictor != this.Bot.GetGameEntity()  )
	{
		isBot = Util.IsBot(Inflictor);
		if ( isBot && isBot.KillingForRevive == true ) {
			return;
		}

		this.responding_to_teamdamage = true;
		if ( this.Randomize(this.TEAMPAIN_HOLDFIRE, Inflictor) == true )
		{
			if ( this.Bot.HasEntityFlag( ENTFLAG.DISGUISED ) )
				{ this.Bot.SayVoice( VOICE.IMA_COVERTOPS ); }
			else
				{ this.Bot.SayVoice( VOICE.HOLD_FIRE ); }
		}
		this.responding_to_teamdamage = false;
	}
};

this.Events[EVENT.GLOBAL_VOICE] = function(WhoSaidIt,VoiceId)
{
	if (!this.Bot) { return; }

	if (this.Bot.DelayResponse) {
		sleep(this.Bot.DelayResponse);
		if (this.Bot){ this.Bot.DelayResponse = null; }
		return;
	}

	if ( WhoSaidIt == this.Bot.GetGameEntity() ) {
		return;
	}

	if(VoiceId == VOICE.G_BYE
		&& this.Randomize(this.GOODBYE_SAYGOODBYE, WhoSaidIt) == true)
	{
		this.Bot.SayVoice(VOICE.G_BYE);
	}
	else if(VoiceId == VOICE.G_HI
		&& this.Randomize(this.HELLO_SAYHELLO, WhoSaidIt) == true)
	{
		this.Bot.SayVoice(VOICE.G_HI);
	}

	this.Bot.DelayResponse = 5;
};
