//==========================================================================================
//
//	This script contains re-usable region trigger tables for ET
//
//==========================================================================================

member Create = function(bounds, type, name)
{
	if (RegionTrigger[type]) {
		trigger = tableDuplicate(RegionTrigger[type]);
		if(name) {
			trigger.Name = format("%s: %s",type,name);
		}
		OnTriggerRegion(bounds,trigger);
		return;
	}
	
	Util.MapDebugPrint("RegionTrigger.Create -> Invalid type specified", true);
};

/*
	Name:		DisableBotPush
	Description:	Disables bot pushing and combat movement in the region. Enables on exit

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.DisableBotPush );
*/
member DisableBotPush =
{
	Name = "disablepush",
	TriggerOnClass = CLASS.ANYPLAYER,
	OnEnter = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			b.DisableBotPush(true);
			b.DisableCombatMovement = true;
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering disablepush." );
		}
	},
	OnExit = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			b.DisableBotPush(false);
			b.DisableCombatMovement = false;
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "exiting disablepush." );
		}
	},
};

/*
	Name:		DisableCombatMovement
	Description:	Disables bot combat movement in the region. Enables on exit

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.DisableCombatMovement );
*/
member DisableCombatMovement =
{
	Name = "disablecm",
	TriggerOnClass = CLASS.ANYPLAYER,
	OnEnter = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			b.DisableCombatMovement = true;
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering disablecm." );
		}
	},
	OnExit = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			b.DisableCombatMovement = false;
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "exiting disablecm." );
		}
	},
};

/*
	Name:		Increase breakable distance
	Description:	Increases breakable distance in the region. Reverts to MinBreakableDist on exit

	Properties:
		MaxBreakableDist - default 160
		MinBreakableDist - default 90

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.BreakableDistance );

	Optional Settings:
		RegionTrigger.BreakableDistance.MinBreakableDist = x;
		RegionTrigger.BreakableDistance.MaxBreakableDist = x;

	Note: Optional settings should be defined after the region trigger is initialized
*/
member BreakableDistance =
{
	Name = "breakabledist",
	TriggerOnClass = CLASS.ANYPLAYER,
	MaxBreakableDist = 160,
	MinBreakableDist = 90,
	OnEnter = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			b.TargetBreakableDist = RegionTrigger.BreakableDistance.MaxBreakableDist;
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering breakabledist." );
		}
	},
	OnExit = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			b.TargetBreakableDist = RegionTrigger.BreakableDistance.MinBreakableDist;
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "exiting breakabledist." );
		}
	},
};

/*
	Name:		Vehicle Trigger
	Description:	Triggers on Heavy Vehicles and Increments Map.VehicleLocation var

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.VehicleTrigger );
*/
member VehicleTrigger =
{
	Name = "VehicleTrigger",
	TriggerOnClass = { CLASS.VEHICLE_HVY, CLASS.VEHICLE_NODAMAGE, CLASS.VEHICLE },
	OnEnter = function(ent)
	{
		name = GetEntName(ent);
		Util.ScriptDebugPrint( name, "regiontrigger", "entering VehicleTrigger." );

		// only track valid mover goals
		if ( !Util.VehicleGoals ) {
			Util.VehiclesInMap();
		}
		if (!Util.VehicleGoals[ent]){ return; }

		if (!Map.VehicleLocation) {
			Map.VehicleLocation = 1;
		}
		else {
			++Map.VehicleLocation;
		}

		triggerInfo =
		{
			Entity = ent,
			Activator = null,
			TagName = name + " at location",
			Action = "arrived",
		};

		SendTrigger(triggerInfo);
	},
	OnExit = function(ent)
	{
		name = GetEntName(ent);
		Util.ScriptDebugPrint( name, "regiontrigger", "exiting VehicleTrigger." );

		// only track valid mover goals
		if(Util.VehicleGoals && !Util.VehicleGoals[ent]){ return; }

		triggerInfo =
		{
			Entity = ent,
			Activator = null,
			TagName = name + " left location",
			Action = "left",
		};

		SendTrigger(triggerInfo);
	},
};

/*
	Name:		Kill Trigger
	Description:	Has the bot commit suicide. Useful in areas where there is no way for a bot to get out

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.KillTrigger );
*/
member KillTrigger =
{
	Name = "KillTrigger",
	TriggerOnClass = CLASS.ANYPLAYER,
	OnEnter = function(ent)
	{
		b = Util.IsBot(ent);
		if (b)
		{
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering KillTrigger." );
			sleep(1);
			b.ExecCommand("kill");
		}
	},
};

/*
	Name:		IntrusionWarning
	Description:	Has one bot of the opposite team warn teammates about enemy intruder if it has a line of sight to the entity

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.IntrusionWarning );
*/
member IntrusionWarning =
{
	Name = "intrusion",
	TriggerOnClass = CLASS.ANYPLAYER,
	OnEnter = function(ent)
	{
		if ( !MAP_TALK || Map.NoBotTalk )
			{ return; }
		t = GetEntTeam(ent);
		foreach ( gameId and bot in BotTable )
		{
			if ( bot.GetTeam() == Map.DefendingTeam && bot.GetTeam() != t && bot.GetTarget() == ent )
			{
				if ( GetEntFlags( ent, ENTFLAG.DISGUISED ) )
					{ bot.SayVoice( VOICE.ENEMY_DISGUISED ); }
				else if ( !bot.GetNearestAlly( CAT.PLAYER ) && RandInt(1,2)<2 )
					{ bot.SayVoice( VOICE.NEED_BACKUP ); }
				else
					{ bot.SayVoice( VOICE.INCOMING ); }
				break;
			}
		}
		sleep(2);
		Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering intrusion." );
	},
	OnExit = function(ent)
	{
		Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "exiting intrusion." );
	},
};

/*
	Name:		IntrusionWarningEngObj
	Description:	Has one bot of the opposite team warn teammates about enemy engineer if it has a line of sight to the entity

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.IntrusionWarningEngObj );
*/
member IntrusionWarningEngObj =
{
	Name = "intrusion_engineer_objective",
	TriggerOnClass = CLASS.ENGINEER,
	Strings =
	{
		"Enemy engineer close to objective!",
		"ENEMY ENGINEER AT OBJECTIVE!",
		"enemy eng at obj!",
		"enemy eng at objective",
		"enemy engi at objective",
		"enemy engineer at objective",
		"Enemy engineer at objective!",
		"Alert! Enemy engineer at objective!",
		"Enemy engineer at objective!",
		"Enemy engineer spotted near objective!",
		"Enemy engineer near objective!",
		"An enemy engineer got through the defenses!",
		"An enemy engineer got through to the objective!",
		"An enemy engineer got near the objective!",
	},
	OnEnter = function(ent)
	{
		if ( !MAP_TALK || Map.NoBotTalk )
			{ return; }
		t = GetEntTeam(ent);
		foreach ( gameId and bot in BotTable )
		{
			if ( bot.GetTeam() == Map.DefendingTeam && bot.GetTeam() != t && bot.GetTarget() == ent )
			{
				if ( !bot.GetNearestAlly( CAT.PLAYER ) )
				{
					if ( RandInt(1,3)<3 )
						{ bot.SayVoice( VOICE.DEFEND_OBJECTIVE ); }
					else
						{ bot.SayVoice( VOICE.REINFORCE_DEF ); }
				}
				else if ( RandInt(1,3)<2 )
					{ bot.SayVoice( VOICE.INCOMING ); }
				sleep(1); // simulate time needed for typing
				rand = RandInt( 0, tableCount(RegionTrigger.IntrusionWarningEngObj.Strings)-1 );
				bot.SayTeam( RegionTrigger.IntrusionWarningEngObj.Strings[rand] );
				break;
			}
		}
		sleep(2);
		Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering intrusion_engineer_objective." );
	},
	OnExit = function(ent)
	{
		Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "exiting intrusion_engineer_objective." );
	},
};

/*
	Name:		AllClear
	Description:	Has the bot say "All clear" if it has no target

	Usage:
		test = OnTriggerRegion( AABB(x,x,x,x,x,x), RegionTrigger.AllClear );
*/
member AllClear =
{
	Name = "AllClear",
	TriggerOnClass = CLASS.ANYPLAYER,
	OnEnter = function(ent)
	{
		if ( !MAP_TALK || Map.NoBotTalk )
			{ return; }
		b = Util.IsBot(ent);
		if (b)
		{
			team = b.GetTeam();
			target = b.GetNearestEnemy( CAT.PLAYER );
			if ( team == Map.DefendingTeam && !target && RandInt(1,15)<2 )
				{ b.SayVoice( VOICE.ALL_CLEAR ); }
			Util.ScriptDebugPrint( GetEntName(ent), "regiontrigger", "entering AllClear." );
		}
	},
};

