//==========================================================================================
//
//	budapest_beta2.gm
//
//	Who	When		What
//------------------------------------------------------------------------------------------
//	palota	1 May 2012	elevators, team doors, trams, DEFEND_axis_bridge, MOBILEMG42, PLANTMINE, MOUNT_boat, MaxViewDistance, TargetBreakableDist, BUILD goals range
//	palota	13 June 2012	routes, roles, use points, cover spots, priorities, ATTACK_allies_defences
//	palota	20 June 2012	fake ATTACK to destroy window at allied MG42, increased DEFENDER2 numbots, higher priority to plant bridge if not enough time left, bridge has random use points, snipe and artillery limited to 1 user
//
//==========================================================================================
//

global Map =
{
	Debug = 0,
	//obj//
	bridge_parts_destroyed = 0,//number of bridge parts destroyed
	gates_destroyed = 0, //number of sewer gates destroyed
	defences_built = false, //
	//garage door//
	garage_1_open = false,//closed
	garage_2_open = false,//closed
	garage_3_open = false,//closed
	//elevators//
	elevator_pos = "bottom", //moving, top, bottom
	elevator_team = 0,//no team 1 = axis, 2 = allies
	elevator_2_pos = "bottom", //moving, top, bottom
	elevator_2_team = 0,//no team 1 = axis, 2 = allies
	//trams//
	right_tram_pos = "bottom",
	left_tram_pos = "top",
	///forward spawn///
	palace_team = TEAM.AXIS,


	Roles =
	{
		AXIS =
		{
			AllBots = true,
			ATTACKER =
			{
				numbots = 10,
			},
			DEFENDER1 =
			{
				numbots = 2,
				crucialClass = CLASS.ENGINEER,
			},
			DEFENDER2 =
			{
				numbots = 10,
			},
		},
		ALLIES =
		{
			DEFENDER =
			{
				numbots = 3,
			},
		}
	},

	//tables//Paththrough//
	///ladders///
	Navigation =
	{
		//generic ladders
		ladder_8 =
		{
			navigate = function(_this)
			{
				_this.Bot.HoldButton(BTN.FORWARD, 8);
				sleep(8);
			},
		},
		ladder_6 =
		{
			navigate = function(_this)
			{
				_this.Bot.HoldButton(BTN.FORWARD, 6);
				sleep(6);
			},
		},
		ladder_5 =
		{
			navigate = function(_this)
			{
				_this.Bot.HoldButton(BTN.FORWARD, 5);
				sleep(5);
			},
		},
		ladder_4 =
		{
			navigate = function(_this)
			{
				_this.Bot.HoldButton(BTN.FORWARD, 4);
				sleep(4);
			},
		},
		ladder_3 =
		{
			navigate = function(_this)
			{
				_this.Bot.HoldButton(BTN.FORWARD, 3);
				sleep(3);
			},
		},
		ladder_2 =
		{
			navigate = function(_this)
			{
				_this.Bot.HoldButton(BTN.FORWARD, 2);
				sleep(2);
			},
		},
		//special ladders
		bottom1_info = { cached = false, wpInfo = {}, },
		ladder_bottom_1 =
		{
			navigate = function(_this)
			{
				if ( !Map.Navigation.bottom1_info.cached )
				{
					Map.Navigation.bottom1_info.wpInfo = Util.WpNameInfo("ladder_bottom_1");
					Map.Navigation.bottom1_info.cached = true;
				}
				_this.AddAimRequest(Priority.High, "facing" , Map.Navigation.bottom1_info.wpInfo.facing);
				_this.Bot.HoldButton(BTN.FORWARD, 8.5);
				sleep(8.5);
			},
		},
		ladder_church_top =
		{
			navigate = function(_this)
			{
				_this.AddAimRequest(Priority.High, "facing" , Vec3(0.465, 0.000, 0.885));
				sleep(1);
				_this.Bot.HoldButton(BTN.BACKWARD, 5.5);
				sleep(6);
			},
		},
		churchSewer_info = { cached = false, wpInfo = {}, },
		ladder_church_sewer =
		{
			navigate = function(_this)
			{
				if ( !Map.Navigation.churchSewer_info.cached )
				{
					Map.Navigation.churchSewer_info.wpInfo = Util.WpNameInfo("ladder_church_sewer");
					Map.Navigation.churchSewer_info.cached = true;
				}
				_this.AddAimRequest(Priority.High, "facing" , Map.Navigation.churchSewer_info.wpInfo.facing);
				_this.Bot.HoldButton(BTN.BACKWARD, 3);
				sleep(3);
			},
		},
		bridgeR_info = { cached = false, wpInfo = {}, },
		ladder_bridge_r =
		{
			navigate = function(_this)
			{
				if ( !Map.Navigation.bridgeR_info.cached )
				{
					Map.Navigation.bridgeR_info.wpInfo = Util.WpNameInfo("bridge_r");
					Map.Navigation.bridgeR_info.cached = true;
				}
				_this.AddAimRequest(Priority.High, "facing" , Map.Navigation.bridgeR_info.wpInfo.facing);
				_this.Bot.HoldButton(BTN.FORWARD, 6);
				sleep(6);
			},
		},
		bridge1_info = { cached = false, wpInfo = {}, },
		ladder_bridge_l =
		{
			navigate = function(_this)
			{
				if ( !Map.Navigation.bridge1_info.cached )
				{
					Map.Navigation.bridge1_info.wpInfo = Util.WpNameInfo("bridge_l");
					Map.Navigation.bridge1_info.cached = true;
				}
				_this.AddAimRequest(Priority.High, "facing" , Map.Navigation.bridge1_info.wpInfo.facing);
				_this.Bot.HoldButton(BTN.FORWARD, 6);
				sleep(6);
			},
		},
	},

	//paththrough switches//
	Switches =
	{
		///elevator 1
		elevator_switch_top =
		{ //pre: this switch calls the elevator to the top
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_switch_top",
			Timeout = 8000,
			ExitConditions =
			{
				f = function(bot){
					return Map.elevator_pos == "moving_up";
				}
			},
			Wait = function()
			{
				return Map.elevator_pos == "top";
			}
		},
		elevator_top =
		{ //pre: this switch sends rider and elevator down
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_top",
			Timeout = 3500,
			Wait = function()
			{
				return Map.elevator_pos != "moving_down";
			},
		},
		elevator_switch_bottom =
		{ //pre: this switch calls the elevator to the bottom
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_switch_bottom",
			Timeout = 8000,
			ExitConditions =
			{
				f = function(bot){
					return Map.elevator_pos == "moving_down";
				}
			},
			Wait = function()
			{
				return Map.elevator_pos == "bottom";
			}
		},
		elevator_bottom =
		{ //pre: this switch sends rider and elevator up
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_bottom",
			Timeout = 3500,
			Wait = function()
			{
				return Map.elevator_pos != "moving_up";
			},
		},

		///elevator 2
		elevator_2_switch_top =
		{ //pre: this switch calls the elevator to the top
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_2_switch_top",
			Timeout = 8000,
			ExitConditions =
			{
				f = function(bot){
					return Map.elevator_2_pos == "moving_up";
				}
			},
			Wait = function()
			{
				return Map.elevator_2_pos == "top";
			}
		},
		elevator_2_top =
		{ //pre: this switch sends rider and elevator down
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_2_top",
			Timeout = 3500,
			Wait = function()
			{
				return Map.elevator_2_pos != "moving_down";
			},
		},
		elevator_2_switch_bottom =
		{ //pre: this switch calls the elevator to the bottom
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_2_switch_bottom",
			Timeout = 8000,
			ExitConditions =
			{
				f = function(bot){
					return Map.elevator_2_pos == "moving_down";
				}
			},
			Wait = function()
			{
				return Map.elevator_2_pos == "bottom";
			}
		},
		elevator_2_bottom =
		{ //pre: this switch sends rider and elevator up
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_2_bottom",
			Timeout = 3500,
			Wait = function()
			{
				return Map.elevator_2_pos != "moving_up";
			},
		},

		///Right tram///
		tram_r_top =
		{
			Enabled = false,
			Priority = 0,
			WaypointName = "tram_r_top",
			Wait = function()
			{
				return Map.right_tram_pos == "bottom";
			},
		},
		tram_r_switch_top =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "tram_r_switch_top",
		},
		tram_r_bottom =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "tram_r_bottom",
			Wait = function()
			{
				return Map.right_tram_pos == "top";
			},
		},
		tram_r_switch_bottom =
		{
			Enabled = false,
			Priority = 0,
			WaypointName = "tram_r_switch_bottom",
		},

		///Left tram///
		tram_l_top =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "tram_l_top",
			Wait = function()
			{
				return Map.left_tram_pos == "bottom";
			},
		},
		tram_l_switch_top =
		{
			Enabled = false,
			Priority = 0,
			WaypointName = "tram_l_switch_top",
		},
		tram_l_bottom =
		{
			Enabled = false,
			Priority = 0,
			WaypointName = "tram_l_bottom",
			Wait = function()
			{
				return Map.left_tram_pos == "top";
			},
		},
		tram_l_switch_bottom =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "tram_l_switch_bottom",
		},

	///normal use_switches///
		garage_1 =
		{
			Enabled = true,
			WaypointName = "garage_1",
			LimitClass = (1<<CLASS.SOLDIER) |
						(1<<CLASS.FIELDOPS) |
						(1<<CLASS.MEDIC),
			LimitDistance = 500,
		},
		garage_2 =
		{
			Enabled = true,
			WaypointName = "garage_2",
			LimitClass = (1<<CLASS.SOLDIER) |
						(1<<CLASS.FIELDOPS) |
						(1<<CLASS.MEDIC),
			LimitDistance = 500,
		},
		garage_3 =
		{
			Enabled = true,
			WaypointName = "garage_3",
			LimitDistance = 600,
		},
	},

	//trigger functions
	//elevator 1
	SetElevatorOwner = function(owner)
	{
		Map.elevator_team = owner;
		b= (owner==TEAM.AXIS);
		Wp.SetWaypointFlag("elevator_top", "closed", false);
		Wp.SetWaypointFlag("elevator_top", "team1", b);
		Wp.SetWaypointFlag("elevator_top", "team2", !b);
		Wp.SetWaypointFlag("elevator_bottom", "closed", false);
		Wp.SetWaypointFlag("elevator_bottom", "team1", b);
		Wp.SetWaypointFlag("elevator_bottom", "team2", !b);
		//=====switches============//
		if (Map.elevator_pos == "bottom")
		{
			Map.Switches.elevator_switch_top.Enabled = true;
			Map.Switches.elevator_bottom.Enabled = true;
		}
		else
		{
			Map.Switches.elevator_top.Enabled = true;
			Map.Switches.elevator_switch_bottom.Enabled = true;
		}
	},
	Axis_Own_Elevator = function( trigger )
	{
		Map.SetElevatorOwner(TEAM.AXIS);
		Util.MapDebugPrint("Axis_Own_Elevator", true);
	},
	Allies_Own_Elevator = function( trigger )
	{
		Map.SetElevatorOwner(TEAM.ALLIES);
		Util.MapDebugPrint("Allies_Own_Elevator", true);
	},
	Nither_Own_Elevator = function( trigger )
	{
		Wp.SetWaypointFlag("elevator_top", "closed", true);
		Wp.SetWaypointFlag("elevator_bottom", "closed", true);
		//=====switches============//
		Map.Switches.elevator_switch_top.Enabled =  false;
		Map.Switches.elevator_top.Enabled = false;
		Map.Switches.elevator_switch_bottom.Enabled = false;
		Map.Switches.elevator_bottom.Enabled =  false;

		Map.elevator_team = 0;//no team 1 = axis, 2 = allies
		Util.MapDebugPrint("Niether_Own_Elevator", true);
	},
	//elevator movement
	Elevator = function(trigger)
	{
		if (ToVector(trigger.Action).z < 0)
		{
			Util.MapDebugPrint("Elevator1 is moving down", true);
			Map.elevator_pos = "moving_down";
			Map.Switches.elevator_switch_top.Enabled = true;
			Map.Switches.elevator_top.Enabled = false;
			sleep(5.8);
			Map.elevator_pos = "stopped_bottom";
			Util.MapDebugPrint("Elevator1 is down", true);
			sleep(1.5);
			if(Map.elevator_pos == "stopped_bottom"){
				Map.elevator_pos = "bottom";
				Map.Switches.elevator_switch_bottom.Enabled = false;
				Map.Switches.elevator_bottom.Enabled = true;
			}
		}
		else
		{
			Util.MapDebugPrint("Elevator1 is moving up", true);
			Map.elevator_pos = "moving_up";
			Map.Switches.elevator_switch_bottom.Enabled = true;
			Map.Switches.elevator_bottom.Enabled = false;
			sleep(5.8);
			Map.elevator_pos = "stopped_top";
			Util.MapDebugPrint("Elevator1 is up", true);
			sleep(1.5);
			if(Map.elevator_pos == "stopped_top"){
				Map.elevator_pos = "top";
				Map.Switches.elevator_switch_top.Enabled = false;
				Map.Switches.elevator_top.Enabled = true;
			}
		}
	},

	//elevator 2
	SetElevator2Owner = function(owner)
	{
		Map.elevator2_team = owner;
		b= (owner==TEAM.AXIS);
		Wp.SetWaypointFlag("elevator_2_top", "closed", false);
		Wp.SetWaypointFlag("elevator_2_top", "team1", b);
		Wp.SetWaypointFlag("elevator_2_top", "team2", !b);
		Wp.SetWaypointFlag("elevator_2_bottom", "closed", false);
		Wp.SetWaypointFlag("elevator_2_bottom", "team1", b);
		Wp.SetWaypointFlag("elevator_2_bottom", "team2", !b);
		//=====switches============//
		if (Map.elevator_2_pos == "bottom")
		{
			Map.Switches.elevator_2_switch_top.Enabled = true;
			Map.Switches.elevator_2_bottom.Enabled = true;
		}
		else
		{
			Map.Switches.elevator_2_top.Enabled = true;
			Map.Switches.elevator_2_switch_bottom.Enabled = true;
		}
	},
	Axis_Own_Elevator_2 = function( trigger )
	{
		Map.SetElevator2Owner(TEAM.AXIS);
		Util.MapDebugPrint("Axis_Own_Elevator_2", true);
	},
	Allies_Own_Elevator_2 = function( trigger )
	{
		Map.SetElevator2Owner(TEAM.ALLIES);
		Util.MapDebugPrint("Allies_Own_Elevator_2", true);
	},
	Nither_Own_Elevator_2 = function( trigger )
	{
		Wp.SetWaypointFlag("elevator_2_top", "closed", true);
		Wp.SetWaypointFlag("elevator_2_bottom", "closed", true);
		//=====switches============//
		Map.Switches.elevator_2_switch_top.Enabled =  false;
		Map.Switches.elevator_2_top.Enabled = false;
		Map.Switches.elevator_2_switch_bottom.Enabled = false;
		Map.Switches.elevator_2_bottom.Enabled =  false;

		Map.elevator2_team = 0;//no team 1 = axis, 2 = allies
		Util.MapDebugPrint("Nither_Own_Elevator_2", true);
	},
	//elevator2 movement
	Elevator_2 = function(trigger)
	{
		if (ToVector(trigger.Action).z < 0)
		{
			Util.MapDebugPrint("Elevator2 is moving down", true);
			Map.elevator_2_pos = "moving_down";
			Map.Switches.elevator_2_switch_top.Enabled = true;
			Map.Switches.elevator_2_top.Enabled = false;
			sleep(5.8);
			Map.elevator_2_pos = "stopped_bottom";
			Util.MapDebugPrint("Elevator2 is down", true);
			sleep(1.5);
			if(Map.elevator_2_pos == "stopped_bottom"){
				Map.elevator_2_pos = "bottom";
				Map.Switches.elevator_2_switch_bottom.Enabled = false;
				Map.Switches.elevator_2_bottom.Enabled = true;
			}
		}
		else
		{
			Util.MapDebugPrint("Elevator2 is moving up", true);
			Map.elevator_2_pos = "moving_up";
			Map.Switches.elevator_2_switch_bottom.Enabled = true;
			Map.Switches.elevator_2_bottom.Enabled = false;
			sleep(5.8);
			Map.elevator_2_pos = "stopped_top";
			Util.MapDebugPrint("Elevator2 is up", true);
			sleep(1.5);
			if(Map.elevator_2_pos == "stopped_top"){
				Map.elevator_2_pos = "top";
				Map.Switches.elevator_2_switch_top.Enabled = false;
				Map.Switches.elevator_2_top.Enabled = true;
			}
		}
	},

	//Trams
	Right_Tram_Activated = function( trigger )
	{
		if (ToVector(trigger.Action).z < 0)
		{
			Util.MapDebugPrint("right tram is moving down", true);
			Map.Switches.tram_r_switch_bottom.Enabled = false;
			Map.Switches.tram_r_top.Enabled = false;
			Wp.SetWaypointFlag("tram_r_top", "closed", true);
			sleep(5.9);
			Map.Switches.tram_r_switch_top.Enabled = true;
			Map.Switches.tram_r_bottom.Enabled = true;
			Wp.SetWaypointFlag("tram_r_bottom", "closed", false);
			Map.right_tram_pos = "bottom";
			Util.MapDebugPrint("right tram is down", true);
		}
		else
		{
			Util.MapDebugPrint("right tram is moving up", true);
			Map.Switches.tram_r_switch_top.Enabled = false;
			Map.Switches.tram_r_bottom.Enabled = false;
			Wp.SetWaypointFlag("tram_r_bottom", "closed", true);
			sleep(8);
			Map.Switches.tram_r_switch_bottom.Enabled = true;
			Map.Switches.tram_r_top.Enabled = true;
			Wp.SetWaypointFlag("tram_r_top", "closed", false);
			Map.right_tram_pos = "top";
			Util.MapDebugPrint("right tram is up", true);
		}
	},
	Left_Tram_Activated = function( trigger )
	{
		if (ToVector(trigger.Action).z < 0)
		{
			Util.MapDebugPrint("left tram is moving down", true);
			Map.Switches.tram_l_switch_bottom.Enabled = false;
			Map.Switches.tram_l_top.Enabled = false;
			Wp.SetWaypointFlag("tram_l_top", "closed", true);
			sleep(5.9);
			Map.Switches.tram_l_switch_top.Enabled = true;
			Map.Switches.tram_l_bottom.Enabled = true;
			Wp.SetWaypointFlag("tram_l_bottom", "closed", false);
			Map.left_tram_pos = "bottom";
			Util.MapDebugPrint("left tram is down", true);
		}
		else
		{
			Util.MapDebugPrint("left tram is moving up", true);
			Map.Switches.tram_l_switch_top.Enabled = false;
			Map.Switches.tram_l_bottom.Enabled = false;
			Wp.SetWaypointFlag("tram_l_bottom", "closed", true);
			sleep(8);
			Map.Switches.tram_l_switch_bottom.Enabled = true;
			Map.Switches.tram_l_top.Enabled = true;
			Wp.SetWaypointFlag("tram_l_top", "closed", false);
			Map.left_tram_pos = "top";
			Util.MapDebugPrint("left tram is up", true);
		}
	},

	Garage1Team = function()
	{
		if (Map.palace_team == TEAM.ALLIES){ return 0; }
		if (!Map.garage_1_open){ return 1<<TEAM.ALLIES; }
		return 1<<TEAM.AXIS;
	},
	Garage2Team = function()
	{
		if (Map.palace_team == TEAM.ALLIES){ return 0; }
		if (!Map.garage_2_open){ return 1<<TEAM.ALLIES; }
		return 1<<TEAM.AXIS;
	},
	Garage3Team = function()
	{
		if (Map.palace_team == TEAM.AXIS){ return 0; }
		if (!Map.garage_3_open){ return 1<<TEAM.ALLIES; }
		return 1<<TEAM.AXIS;
	},

	//garages
	Trigger_garage_1 = function( trigger )
	{
		sleep(2.25); //wait is 2.24 in map script
		Map.garage_1_open = ToVector(trigger.Action).x < 0;
		Map.Switches.garage_1.LimitTeam = Map.Garage1Team();
		if (Map.garage_1_open) { d = 900; } else { d = 500; }
		Map.Switches.garage_1.LimitDistance = d;
		Util.MapDebugPrint("Trigger_garage_1", true);
	},
	Trigger_garage_2 = function( trigger )
	{
		sleep(2.25); //wait is 2.24 in map script
		Map.garage_2_open = ToVector(trigger.Action).y < 0;
		Map.Switches.garage_2.LimitTeam = Map.Garage2Team();
		if (Map.garage_2_open) { d = 900; } else { d = 500; }
		Map.Switches.garage_2.LimitDistance = d;
		Util.MapDebugPrint("Trigger_garage_2", true);
	},

	Trigger_garage_3 = function( trigger )
	{ //this is the door to the second elevator
		sleep(2.25); //wait is 2.24 in map script
		Map.garage_3_open = ToVector(trigger.Action).x < 0;
		Map.Switches.garage_3.LimitTeam = Map.Garage3Team();
		Util.MapDebugPrint("Trigger_garage_3", true);
	},

	//sewer gates
	SetGateDestroyed = function(name)
	{
		Wp.SetWaypointFlag(name + "_gate_block_0", "closed", true);
		Map.gates_destroyed += 1;
		if (name!="south") {
			Util.EnableGoal("ROUTE_elevator2");
			Util.EnableGoal("ROUTE_ladder2");
		}
		Util.MapDebugPrint(name + "_Gate_Destroyed");
	},
	East_Gate_Destroyed = function( trigger )
	{
		Map.SetGateDestroyed("east");
	},
	West_Gate_Destroyed = function( trigger )
	{
		Map.SetGateDestroyed("west");
	},
	South_Gate_Destroyed = function( trigger )
	{
		Util.EnableGoal("ROUTE_south_gate2");
		Map.SetGateDestroyed("south");
	},

	//bridge defences
	Bridge_Defences_Built = function( trigger )
	{
		Wp.SetWaypointFlag("bridge_defences_door", "team1", true);
		Map.defences_built = true;
		SetAvailableMapGoals(TEAM.ALLIES, true, "ATTACK_allies_defences.*");
		Util.MapDebugPrint("Bridge_Defences_Built");
	},
	Bridge_Defences_Destroyed = function( trigger )
	{
		Wp.SetWaypointFlag("bridge_defences_door", "team1", false);
		Map.defences_built = false;
		SetAvailableMapGoals(TEAM.ALLIES, false, "ATTACK_allies_defences.*");
		if (GetGameTimeLeft() < 500) {
			SetGoalPriority( "PLANT_.*_bridge_support.*", 0.81, TEAM.ALLIES);
		}
		Util.MapDebugPrint("Bridge_Defences_Destroyed");
	},

	//Bridge Main objective
	SetJumpLow = function(name, count, b)
	{
		for(i=0; i<count; i+=1)
		{
			Wp.SetWaypointFlag("bridge_" + name + "_jump_" + i, "jumplow", b);
		}
	},
	East_Bridge_Destroyed = function( trigger )
	{
		Map.SetJumpLow("east", 5, true);
		Wp.SetWaypointFlag("bridge_east_blocker_0", "closed", true);
		Wp.SetWaypointFlag("bridge_east_blocker_1", "closed", true);
		Map.bridge_parts_destroyed += 1;
		SetAvailableMapGoals( TEAM.ALLIES, Map.bridge_parts_destroyed == 2, "PLANT_Main_bridge_support");
		Util.MapDebugPrint("East_Bridge_Destroyed");
	},
	West_Bridge_Destroyed = function( trigger )
	{
		Map.SetJumpLow("west", 7, true);
		Wp.SetWaypointFlag("bridge_west_blocker_0", "closed", true);
		Wp.SetWaypointFlag("bridge_west_blocker_1", "closed", true);
		Map.bridge_parts_destroyed += 1;
		SetAvailableMapGoals( TEAM.ALLIES, Map.bridge_parts_destroyed == 2, "PLANT_Main_bridge_support");
		Util.MapDebugPrint("West_Bridge_Destroyed");
	},

	SetSpawn1 = function(bot)
	{
		if (bot.GetTeam() == TEAM.AXIS)
		{
			if (Map.palace_team == TEAM.AXIS){ s=2; }
			else if (RandInt(0,10) > 5){ s=4; }
			else{ s=1; }
			bot.ChangeSpawnPoint(s);
		}
	},

	//Palace Flag
	SetTeam = function(team)
	{
		Map.palace_team = team;
		for(i=0; i<5; i+=1)
		{
			Wp.SetWaypointFlag("team_capture_" + i, "team1", team==TEAM.AXIS);
			Wp.SetWaypointFlag("team_capture_" + i, "team2", team==TEAM.ALLIES);
		}
		foreach(bot in BotTable)
		{
			Map.SetSpawn1(bot);
		}
		Map.Switches.garage_1.LimitTeam = Map.Garage1Team();
		Map.Switches.garage_2.LimitTeam = Map.Garage2Team();
		Map.Switches.garage_3.LimitTeam = Map.Garage3Team();
	},

	Allies_Capture_Flag = function( trigger )
	{
		Map.SetTeam(TEAM.ALLIES);
		SetAvailableMapGoals(TEAM.AXIS, true, "CHECKPOINT_forward_flag");
		SetAvailableMapGoals( TEAM.AXIS, false, Groups.group1); //"axis_palace" flags
		SetAvailableMapGoals( TEAM.ALLIES, true, Groups.group6); //"allies_bridge" flags
		SetAvailableMapGoals( TEAM.ALLIES, false, Groups.group2); //"allies_palace" flags
		Util.SetGoalRange("BUILD_Second_Elevator_Controls", 1600);
		Util.SetMaxUsersInProgress(2, "PLANT_Bridge_Defences");

		SetGoalPriority( "PLANT_Bridge_Defences", 0.81, TEAM.ALLIES);
		SetGoalPriority( "PLANT_.*_S.*Gate", 0.81, TEAM.ALLIES);
		SetGoalPriority( "PLANT_.*_bridge_support.*", 0.81, TEAM.ALLIES);

		Util.MapDebugPrint("Allies_Capture_Flag");
		sleep(15);
		if( Map.palace_team == TEAM.ALLIES) {
			SetAvailableMapGoals( TEAM.AXIS, true, Groups.group5); //"axis_bridge" flags
			Util.SetRoleForGoals("CHECKPOINT_forward_flag", ROLE.ATTACKER);
		}
	},
	Axis_Capture_Flag = function( trigger )
	{
		Map.SetTeam(TEAM.AXIS);
		SetAvailableMapGoals( TEAM.AXIS, true, Groups.group1); //"axis_palace" flags
		SetAvailableMapGoals( TEAM.AXIS, false, Groups.group5); //"axis_bridge" flags
		SetAvailableMapGoals( TEAM.ALLIES, true, Groups.group2); //"allies_palace" flags
		SetAvailableMapGoals( TEAM.ALLIES, false, Groups.group6); //"allies_bridge" flags
		Util.ClearRoleForGoals("CHECKPOINT_forward_flag", ROLE.ATTACKER);
		Util.SetGoalRange("BUILD_Second_Elevator_Controls", 0);

		SetGoalPriority( "PLANT_Bridge_Defences", 0.7, TEAM.ALLIES);
		SetGoalPriority( "PLANT_.*_S.*Gate", 0.7, TEAM.ALLIES);
		SetGoalPriority( "PLANT_.*_bridge_support.*", 0.6, TEAM.ALLIES);
		Util.MapDebugPrint("Axis_Capture_Flag");
	},

	windowMG_Destroyed = function ( trigger )
	{
		Util.DisableGoal("ATTACK_allies_bridge_mg");
		SetGoalPriority( "ATTACK_allies_bridge_mg", 0, TEAM.ALLIES);
		Util.MapDebugPrint("windowMG_Destroyed");
	}
};

global OnMapLoad = function()
{
	//use waypoints
	Util.AddUseWp("PLANT_West_bridge_support", { "west_bridge_front_plant", "west_bridge_rear_plant" });
	Util.AddUseWp("PLANT_East_bridge_support", { "east_bridge_front_plant", "east_bridge_rear_plant" });
	Util.AddUseWp("PLANT_Bridge_Defences", { "bridge_defences_plant", "bridge_defences_plant2" });
	Util.AddUsePoint("PLANT_South_Sewer_Gate", { Vec3(-1612.847, -331.162, -1007.875), Vec3(-1621.703, -221.398, -999.729) });
	Util.AddUsePoint("PLANT_East_Sewer_Gate", { Vec3(683.088, 3450.980, -973.875), Vec3(780.183, 3444.837, -973.700) });
	Util.AddUsePoint("PLANT_West_Sewer_Gate", { Vec3(-1631.327, 2170.543, -973.875), Vec3(-1637.408, 2065.886, -973.875) });

	//triger functions
	OnTrigger( "GRENADE_allied_mg Exploded.", Map.windowMG_Destroyed );
	//flag
	OnTrigger("The Allies have captured the Forward Bunker!", Map.Allies_Capture_Flag);
	OnTrigger("The Axis have captured the Forward Bunker!", Map.Axis_Capture_Flag);
	//elevator 1
	OnTrigger("The Axis have repaired the First Elevator Generator!", Map.Axis_Own_Elevator);
	OnTrigger("The Allies have repaired the First Elevator Generator!", Map.Allies_Own_Elevator);
	OnTrigger("The First Elevator Generator has been Dammaged!", Map.Nither_Own_Elevator);
	OnTrigger( "elevator_goto", Map.Elevator );
	//elevator 2
	OnTrigger("The Axis have repaired the Second Elevator Generator!", Map.Axis_Own_Elevator_2);
	OnTrigger("The Allies have repaired the Second Elevator Generator!", Map.Allies_Own_Elevator_2);
	OnTrigger("The Second Elevator Generator has been Dammaged!", Map.Nither_Own_Elevator_2);
	OnTrigger( "elevator_2_goto", Map.Elevator_2 );
	//Trams
	OnTrigger("tram_r_goto", Map.Right_Tram_Activated);
	OnTrigger("tram_l_goto", Map.Left_Tram_Activated);
	//sewer gates///
	OnTrigger("The Allies have destroyed the East Sewer Gate!", Map.East_Gate_Destroyed);
	OnTrigger("The Allies have destroyed the West Sewer Gate!", Map.West_Gate_Destroyed);
	OnTrigger("The Allies have destroyed the South Sewer Gate!", Map.South_Gate_Destroyed);
	//garage doors
	OnTrigger("g_door_l_goto", Map.Trigger_garage_1);
	OnTrigger("g_door_l1_goto", Map.Trigger_garage_2);
	OnTrigger("g_door_l2_goto", Map.Trigger_garage_3);
	//bridge defences
	OnTrigger("The Axis have Built the Bridge Defences!", Map.Bridge_Defences_Built);
	OnTrigger("The Allies have destroyed the Bridge Defences!", Map.Bridge_Defences_Destroyed);
	//bridge objectives
	OnTrigger("The Allies have destroyed the East Bridge Support!", Map.East_Bridge_Destroyed);
	OnTrigger("The Allies have destroyed the West Bridge Support!", Map.West_Bridge_Destroyed);

	Util.UpdateSwitchData();

	//start waypoints
	//bridge jump waypoints
	Map.SetJumpLow("east", 5, false);
	Map.SetJumpLow("west", 7, false);
	//unblocked paths at start\\
	Wp.SetWaypointFlag("bridge_west_blocker_0", "closed", false);
	Wp.SetWaypointFlag("bridge_west_blocker_1", "closed", false);
	Wp.SetWaypointFlag("bridge_east_blocker_0", "closed", false);
	Wp.SetWaypointFlag("bridge_east_blocker_1", "closed", false);
	Wp.SetWaypointFlag("east_gate_block_0", "closed", false);
	Wp.SetWaypointFlag("west_gate_block_0", "closed", false);
	Wp.SetWaypointFlag("south_gate_block_0", "closed", false);
	Wp.SetWaypointFlag("bridge_defences_door", "team1", false);
	//elevator waypoints at start//
	Wp.SetWaypointFlag("elevator_top", "closed", true);
	Wp.SetWaypointFlag("elevator_bottom", "closed", true);
	Wp.SetWaypointFlag("elevator_2_top", "closed", true);
	Wp.SetWaypointFlag("elevator_2_bottom", "closed", true);
	//right tram is down
	Wp.SetWaypointFlag("tram_r_top", "closed", true);
	Wp.SetWaypointFlag("tram_r_bottom", "closed", false);
	//left tram is up
	Wp.SetWaypointFlag("tram_l_top", "closed", false);
	Wp.SetWaypointFlag("tram_l_bottom", "closed", true);

	//goals availability
	Util.DisableGoal(".*", true);
	Util.DisableGoal("ROUTE_elevator2");
	Util.DisableGoal("ROUTE_ladder2");
	Util.DisableGoal("ROUTE_south_gate2");
	Util.EnableGoal(".*cabinet");
	SetAvailableMapGoals( TEAM.ALLIES, true, Groups.group8);
	SetAvailableMapGoals( TEAM.AXIS, true, Groups.group9);
	// Axis_Capture_Flag is triggered at start

	Util.SetRoleForGoals("DEFEND_axis_palace_tram.*", ROLE.DEFENDER2);
	Util.SetRoleForGoals("ATTACK_allies_defences.*", ROLE.DEFENDER);

	// ** PRIORITY ***//
	SetGoalPriority( "BUILD_Bridge_Defences", 0.91 );
	SetGoalPriority( "CHECKPOINT_forward_flag", 0.6 );
	SetGoalPriority( "SNIPE_axis_palace.*", 0.81 );
	SetGoalPriority( "ATTACK_allies_bridge_mg", 0.75, TEAM.ALLIES);
	SetGoalPriority( "PLANT_Second_Elevator_Controls", 0.85, TEAM.ALLIES, CLASS.COVERTOPS);

	// *** MAX USERS PER GOAL ***
	foreach (goal in { "BUILD_Bridge_Defences", ".*_First_Elevator_Controls",
		"REPAIR.*", "DEFEND_.*", "MOUNT.*", "CALLARTILLERY.*", "SNIPE.*",
		"PLANT_Second_Elevator_Controls" }){
		Util.SetMaxUsersInProgress( 1, goal);
	}

	//camptime//
	SetMapGoalProperties( "ATTACK_.*", {MinCampTime=10, MaxCampTime=30});
	SetMapGoalProperties( "DEFEND_.*", {MinCampTime=30, MaxCampTime=120});
	SetMapGoalProperties( "SNIPE_.*", {MinCampTime=40, MaxCampTime=100});
	SetMapGoalProperties( "MOUNTMG42_.*", {MinCampTime=15, MaxCampTime=80});
	SetMapGoalProperties( "MOBILEMG42_.*", {MinCampTime=60, MaxCampTime=150});
	SetMapGoalProperties( "MOUNT_.*", {MinCampTime=60, MaxCampTime=180});

	MapRoutes =
	{
		PLANT_Bridge_Defences = //allies obj
		{
			ROUTE_palace_spawn =
			{
				ROUTE_elevator2 =
				{
					ROUTE_sewer_split_1 =
					{
						ROUTE_sewer_split_2 = {},
					},
				},
				ROUTE_ladder2 =
				{
					ROUTE_sewer_split_1 = {},
				},
				ROUTE_main_split = {
					ROUTE_tram_split =
					{
						Weight = 2,
						ROUTE_tram_r_top = { ROUTE_tram_r_bottom = {}},
						ROUTE_tram_l_top = { ROUTE_tram_l_bottom = {}},
					},
					ROUTE_defences_jumpoff = {},
				},
			},
		},
		PLANT_East_Sewer_Gate =
		{
			ROUTE_palace_spawn =
			{
				ROUTE_elevator2_eng = {},
				ROUTE_ladder2_eng = {},
			},
			ROUTE_church_spawn =
			{
				ROUTE_defences_jumpoff = {},
			},
		},
		PLANT_Main_bridge_support = //allies obj
		{
			ROUTE_palace_spawn =
			{
				ROUTE_elevator2 =
				{
					ROUTE_sewer_split_1 = {
						ROUTE_south_gate = {
							Weight = 2,
							ROUTE_south_gate2 = {}
						},
						ROUTE_east_sewer = {
							ROUTE_east_balcony = {},
							ROUTE_east_door = {},
						},
					},
				},
				ROUTE_ladder2 =
				{
					ROUTE_sewer_split_1 = {},
				},
			},
		},
		CHECKPOINT_forward_flag =
		{
			ROUTE_church_spawn =
			{
				ROUTE_church_spawn_r_split =
				{
					Weight = 3,
					ROUTE_church_r_split = {},
					ROUTE_church_side = {},
				},
				ROUTE_church_spawn_l_split =
				{
					ROUTE_church_l_split = {},
				},
				ROUTE_church_sewer_enter =
				{
					Weight = 6,
					ROUTE_elevator1_bottom = { ROUTE_elevator1_top = {}},
					ROUTE_ladder1 = {},
				},
			},
			ROUTE_axis_west_spawn =
			{
				ROUTE_south_gate =
				{
					Weight = 2,
					ROUTE_sewer_south_connect =
					{
						ROUTE_sewer_split_1 =
						{
							ROUTE_elevator2_eng = {},
							ROUTE_ladder2_eng = {},
						},
					},
				},
				ROUTE_tram_r_bottom = { ROUTE_tram_r_top = {}},
				ROUTE_tram_l_bottom = { ROUTE_tram_l_top = {}},
			},
			ROUTE_axis_east_spawn =
			{
				ROUTE_east_sewer =
				{
					ROUTE_sewer_split_1 = {},
				},
				ROUTE_tram_r_bottom = {},
				ROUTE_tram_l_bottom = {},
			},
		},
	};

	MapRoutes.PLANT_Main_bridge_support.ROUTE_palace_spawn.ROUTE_main_split = MapRoutes.PLANT_Bridge_Defences.ROUTE_palace_spawn.ROUTE_main_split;
	MapRoutes.PLANT_West_Sewer_Gate = MapRoutes.PLANT_East_Sewer_Gate;
	MapRoutes["PLANT_South_S.*Gate"] = MapRoutes.PLANT_East_Sewer_Gate; // N!tmod has wrong goal name PLANT_South_SeGate
	MapRoutes["PLANT_.*st_bridge_support.*"] = MapRoutes.PLANT_Main_bridge_support;
	MapRoutes["ATTACK_allies_bridge.*"] = MapRoutes.PLANT_Main_bridge_support;
	MapRoutes["ATTACK_allies_defences.*"] = MapRoutes.PLANT_Bridge_Defences;
	Util.Routes(MapRoutes);

	Util.AddInvVehicle("MOVER_tank"); //boat
	Util.MapDebugPrint( "Omni-bot map script for " + GetMapName() + " executed." );
};


global OnBotJoin = function( bot )
{
	bot.MaxViewDistance = 2800; //fog
	bot.TargetBreakableDist = 150.0;
	Map.SetSpawn1(bot);
};

global Groups =
{
//Axis at start
	group1 =
	{
		".*_axis_palace.*",
		"BUILD_Neutral_Command_Post",
		"PLANT_First_Elevator_Controls",
	},
//Allies at start
	group2 =
	{
		"SNIPE_allies_palace.*",
		"CHECKPOINT_forward_flag",
		".*_First_Elevator_Controls",
	},

//Axis after palace flag-lost
	group5 =
	{
		".*_axis_bridge.*",
		".*MG42_axis_mg42",
		"MOUNT_boat",
	},
//Allies after palace flag-capture
	group6 =
	{
		".*_allies_bridge.*",
		".*MG42_allies_mg42",
		".*_Second_Elevator_Controls",
		".*_Neutral_Command_Post",
	},

//Allies
	group8 =
	{
		"PLANT_Bridge_Defences",
		"PLANT_West_bridge_support.*",
		"PLANT_East_bridge_support.*",
		"PLANT_.*_S.*Gate",
	},
//Axis
	group9 =
	{
		"PLANT_Neutral_Command_Post",
		"BUILD_Bridge_Defences",
		".*_Second_Elevator_Controls",
	},
};
