global Map =
{
	Mount_axis_MG1 = "MOUNTMG42_650",
	Mount_axis_MG2 = "MOUNTMG42_549",
	Repair_axis_MG1 = "REPAIRMG42_650",
	Repair_axis_MG2 = "REPAIRMG42_549",
	Mount_allied_MG1 = "MOUNTMG42_179",
	Mount_allied_MG2 = "MOUNTMG42_180",
	Repair_allied_MG1 = "REPAIRMG42_179",
	Repair_allied_MG2 = "REPAIRMG42_180",

	Debug = false,
	Talk = true,
	GateIsBreached = false,
	InnerSpawnPoint = 0, // 0: nobody, 1: Axis, 2: Allies
	Door1Status = 0, //closed
	Door3Status = 0, //closed
	Door4Status = 0, //closed

	Switches =
	{
		door1 =
		{
			Enabled = true,
			Priority = 0, //crapshoot: always set to 0 when using path through
			WaypointName = "door_switch1",
			Timeout = 1000,
			AimPosition = Vector3(-2380, -1832, 191),
			Wait = function()
			{
				if ( Map.Door1Status == 1 )
				{
					sleep(1.5);
					return true;
				}
				return false;
			},
		},
		door3_1 =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "door_switch3_1",
			AimPosition = Vector3(-236, 1476, -19),
			Timeout = 1300,
			Wait = function()
			{
				if ( Map.Door3Status == 1 )
				{
					sleep(1.5);
					return true;
				}
				return false;
			},
		},
		door3_2 =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "door_switch3_2",
			Timeout = 1300,
			AimPosition = Vector3(-71, 1416, -20),
			Wait = function()
			{
				if ( Map.Door3Status == 1 )
				{
					sleep(1.5);
					return true;
				}
				return false;
			},
		},
		door4_1 =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "door_switch4_1",
			Timeout = 1300,
			AimPosition = Vector3(130, 1016, 50),
			Wait = function()
			{
				if ( Map.Door4Status == 1 )
				{
					sleep(1.5);
					return true;
				}
				return false;
			},
		},
		door4_2 =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "door_switch4_2",
			Timeout = 1300,
			AimPosition = Vector3(299, 902, 48),
			Wait = function()
			{
				if ( Map.Door4Status == 1 )
				{
					sleep(1.5);
					return true;
				}
				return false;
			},
		},
	},

	testTraceLineThread = function()
	{
		// two map coordinates at east side window:
		start = Vec3(1357.5, -1830, 220);
		end = Vec3(1357.5, -1845, 220);
		while ( true )
		{
			tr = TraceLine( start, end, null, TRACE.SHOT, 0, false );
			if( tr.fraction < 1 )
			{
				if( Map.Debug )
					{ DrawDebugLine( start, end, COLOR.RED, 2 ); }
			}
			else
			{
				if( Map.Debug )
					{ DrawDebugLine( start, end, COLOR.GREEN, 2 ); }
				thread( Map.window_thread_func );
				exit();
			}
			sleep(2);
		}
	},

	window_thread_func = function()
	{
		window_pos = Vec3(1335, -1790, 200);
		while ( true )
		{
			foreach ( id and bot in BotTable )
			{
				if ( bot.GetTeam() == TEAM.AXIS && bot.HasLineOfSightTo(window_pos) )
				{
					bot.SayTeam( "Achtung! The East window has been breached. Defend it!" );
					Util.MapDebugPrint( "Axis bot is warning team members about broken window now." );
					exit(); // once is enough, exit thread
				}
			}
			sleep(5);
		}
	},

	gate_Breached = function( trigger )
	{
		//Util.MapDebugPrint( "gate_Breached" );
		Map.GateIsBreached = true;
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"DEFEND_axis_phase2.*",
			"MOBILEMG42_axismg_phase2.*",
		});
	},

	docs_Stolen = function( trigger )
	{
		//Util.MapDebugPrint( "docs_Stolen" );
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"DEFEND_axis_cappoint",
			Map.Mount_axis_MG1,
			Map.Mount_axis_MG2,
		});

		for ( i = 1; i < 10; i += 1 ) {
			Wp.SetWaypointFlag( "tempsprint" + i, "sprint", true );
		}
	},

	docs_Returned = function( trigger )
	{
		//Util.MapDebugPrint( "docs_Returned" );
		SetAvailableMapGoals( TEAM.AXIS, false, "DEFEND_axis_cappoint" );
		if( Map.InnerSpawnPoint == 2 )
		{
			SetAvailableMapGoals( TEAM.AXIS, false, {
				"DEFEND_axis_phase1.*",
				Map.Mount_axis_MG1,
				Map.Mount_axis_MG2,
			});
		}

		for ( i = 1; i < 10; i += 1 ) {
			Wp.SetWaypointFlag( "tempsprint" + i, "sprint", false );
		}
	},

	Allies_Capture_Flag = function( trigger )
	{
		//Util.MapDebugPrint( "Allies_Capture_Flag" );
		Map.InnerSpawnPoint = 2; // Allies
		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"BUILD_East_Ramp",
			"BUILD_West_Ramp",
		});
		SetAvailableMapGoals( TEAM.AXIS, false, {
			"CALLARTILLERY_axis_phase1.*",
			"MOBILEMG42_axismg_phase2.*",
			"MOBILEMORTAR.*",
			"DEFEND_axis_phase1.*",
			Map.Mount_axis_MG1,
			Map.Mount_axis_MG2,
		});
	},

	Axis_Capture_Flag = function( trigger )
	{
		//Util.MapDebugPrint( "Axis_Capture_Flag" );
		Map.InnerSpawnPoint = 1; // Axis
		if (Map.GateIsBreached)
		{
			SetAvailableMapGoals( TEAM.AXIS, true, "MOBILEMG42_axismg_phase2.*" );
		}
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"BUILD_East_Ramp",
			"BUILD_West_Ramp",
		});
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"CALLARTILLERY_axis_phase1.*",
			"MOBILEMORTAR.*",
			"DEFEND_axis_phase1.*",
			Map.Mount_axis_MG1,
			Map.Mount_axis_MG2,
		});
	},

	Door1_Moving = function( trigger )
	{
		if ( trigger.Action == "opening" )
		{
			Map.Door1Status = 1; //opened
			Map.Switches.door1.Enabled = false;
			//Util.MapDebugPrint("opening");
		}
		else
		{
			Map.Door1Status = 0; //closed
			Map.Switches.door1.Enabled = true;
		}
	},

	Door3_Moving = function( trigger )
	{
		if ( trigger.Action == "opening" )
		{
			//Wp.SetWaypointFlag( "doorhack", "closed", false );
			Map.Door3Status = 1; //opened
			Map.Switches.door3_1.Enabled = false;
			Map.Switches.door3_2.Enabled = false;
			//Util.MapDebugPrint("opening");
		}
		else
		{
			//Wp.SetWaypointFlag( "doorhack", "closed", true );
			Map.Door3Status = 0; //closed
			Map.Switches.door3_1.Enabled = true;
			Map.Switches.door3_2.Enabled = true;
		}
	},

	Door4_Moving = function( trigger )
	{
		if ( trigger.Action == "opening" )
		{
			Map.Door4Status = 1;
			Map.Switches.door4_1.Enabled = false;
			Map.Switches.door4_2.Enabled = false;
			//Util.MapDebugPrint("opening");
		}
		else
		{
			Map.Door3Status = 0;
			Map.Switches.door4_1.Enabled = true;
			Map.Switches.door4_2.Enabled = true;
		}
	},
};

global OnMapLoad = function()
{
	// *** TRIGGERS ***
	OnTrigger( "The Main Entrance has been breached!", Map.gate_Breached );
	OnTrigger( "Allies have stolen Die Dokumente!", Map.docs_Stolen );
	OnTrigger( "Flag returned Die Dokumente!", Map.docs_Returned );
	OnTrigger( "Allies captured the Flag!", Map.Allies_Capture_Flag );
	OnTrigger( "Axis captured the Flag!", Map.Axis_Capture_Flag );
	OnTrigger( "alliespawndoor_Moving", Map.Door1_Moving );
	OnTrigger( "alliespawndoor_3_Moving", Map.Door3_Moving );
	OnTrigger( "alliespawndoor_4_Moving", Map.Door4_Moving );

	SetAvailableMapGoals( TEAM.ALLIES, false, {
		Map.Repair_axis_MG1,
		Map.Repair_axis_MG2,
		Map.Mount_axis_MG1,
		Map.Mount_axis_MG2,
		"PLANT_Axis_Tower",
		"PLANT_Axis_Watertank",
		"CALLARTILLERY_axis_.*",
		"SNIPE_axis_.*",
		"MOBILEMORTAR.*",
		"MOBILEMG42_axismg_.*",
		"DEFEND_axis_.*",
	});
	SetAvailableMapGoals( TEAM.AXIS, false, {
		"MOBILEMG42_axismg_.*",
		"DEFEND_axis_phase2.*",
		"DEFEND_axis_cappoint",
		Map.Repair_allied_MG1,
		Map.Repair_allied_MG2,
		Map.Mount_allied_MG1,
		Map.Mount_allied_MG2,
	});

	// Max. users & camp time
	Util.SetMaxUsersInProgress( 1, "ATTACK_.*" );
	Util.SetMaxUsersInProgress( 1, "DEFEND_.*" );
	Util.SetMaxUsersInProgress( 1, "MOUNTMG42_.*" );
	Util.SetMaxUsersInProgress( 1, "BUILD_.*" );
	Util.SetMaxUsersInProgress( 1, "PLANT_.*" );
	Util.SetMaxUsersInProgress( 3, "FLAG_.*" );
	Util.SetMaxUsersInProgress( 2, "CHECKPOINT_.*" );

	SetMapGoalProperties( "SNIPE_.*", { MaxCampTime=90 } );
	SetMapGoalProperties( "DEFEND_.*", { MaxCampTime=60 } );
	SetMapGoalProperties( "MOUNTMG42_.*", { MinCampTime=30, MaxCampTime=180 } );
	SetMapGoalProperties( "MOBILEMG42_.*", { MaxCampTime=120 } );

	// Priority
	SetGoalPriority( "BUILD_East_Fueltank", 0.8 );
	SetGoalPriority( "CHECKPOINT_kloster_flag", 0.8 );

	// initialization of some waypoint flags
	for ( i = 1; i < 10; i += 1 ) {
		Wp.SetWaypointFlag( "tempsprint" + i, "sprint", false );
	}

	// monitor window status
	if ( Map.Talk && MAP_TALK )
		{ thread( Map.testTraceLineThread ); }

	// *** ROUTES ***
	Maproutes =
	{
		CHECKPOINT_kloster_flag =
		{
			ROUTE_allied_spawn =
			{
				ROUTE_axismg_phase2_2 = {},
				ROUTE_back_door = {},
			},
		},
		CAPPOINT_692 =
		{
			ROUTE_cappoint =
			{
				ROUTE_direct = {},
				ROUTE_grille = {},
				ROUTE_flag_room = {},
				ROUTE_mirror_room =
				{
					ROUTE_ladder =
					{
						ROUTE_north_route3 = {}
					}
				},
				ROUTE_back_door =
				{
					ROUTE_grille = {},
					ROUTE_back_door2 = {},
					ROUTE_north_route =
					{
						ROUTE_north_route2 =
						{
							ROUTE_north_route3 = {}
						}
					},
				},
			},
		}
	};
	Maproutes.FLAG_Die_Dokumente = Maproutes.CHECKPOINT_kloster_flag;
	Util.Routes(Maproutes);
	Util.UpdateSwitchData();

	Util.MapDebugPrint( "Omni-bot map script for Monte Cassino executed." );
};
