global Map =
{
	//set status's for conditionals
	MainDoorStatus = 0, //intact
	SideDoorStatus = 0,
	EastPartsStatus = 0, //0 home, 1 stolen, 2 secured
	WestPartsStatus = 0,
	CPStatus = 0, //not allies
	AxisShiftedToParts = 0, // still in bunker defense

	//dyno counters
	MainDyno = 0,
	SideDyno = 0,

	Roles =
	{
		// split the defense into east and west teams
		AXIS =
		{
			AllBots = true,
			DEFENDER2 = // west
			{
				crucialClass = CLASS.ENGINEER, // for mines
				numbots = 4,
			},
			DEFENDER1 = // east
			{
				crucialClass = CLASS.ENGINEER, // for mines
				numbots = 4,
			},
		},
		// up to 5 allies will spawn at cp
		ALLIES =
		{
			ATTACKER2 =
			{
				numbots = 5,
			},
		},
	},

	Axis_Road_MG_Nest_Built = function()
	{
		Util.MapDebugPrint( "Axis_Road_MG_Nest_Built" );
	},

	Axis_Road_MG_Nest_Destroyed = function()
	{
		Util.MapDebugPrint( "Axis_Road_MG_Nest_Destroyed" );
	},

	Axis_Watchtower_MG_Nest_Built = function()
	{
		Util.MapDebugPrint( "Axis_Watchtower_MG_Nest_Built" );
	},

	Axis_Watchtower_MG_Nest_Destroyed = function()
	{
		Util.MapDebugPrint( "Axis_Watchtower_MG_Nest_Destroyed" );
	},

	Bunker_MG_Nest_Built = function()
	{
		Util.MapDebugPrint( "Bunker_MG_Nest_Built" );
	},

	Bunker_MG_Nest_Destroyed = function()
	{
		Util.MapDebugPrint( "Bunker_MG_Nest_Destroyed" );
	},

	Allied_Command_Post_Built = function()
	{
		Map.CPStatus = 1;

		Util.ChangeSpawnForRole( TEAM.ALLIES, ROLE.ATTACKER2, 1 );
		Util.DisableGoal("ROUTE_cpassist");

		Util.DisableGroup( "cpdefense", TEAM.AXIS );
		Map.ShiftAxisToParts();
		SetAvailableMapGoals( TEAM.AXIS, false, "PLANTMINE_rBunkerEast[23]" );
		SetAvailableMapGoals( TEAM.AXIS, true, "PLANT_Command_Post" );

		Util.MapDebugPrint( "Allied_Command_Post_Built" );
	},

	Axis_Command_Post_Built = function()
	{
		if ( Map.FirstAxisEng ) {
			Map.FirstAxisEng.crucialClass = null;
			Map.FirstAxisEng.ChangeSpawnPoint(3);
			Map.FirstAxisEng = null;
		}

		Util.MapDebugPrint( "Axis_Command_Post_Built" );
	},

	Command_Post_Destroyed = function()
	{
		Map.CPStatus = 0;

		if ( Map.SideDoorStatus == 1 )
		{
			Util.EnableGoal("ROUTE_cpassist");
			if ( Map.EastPartsStatus == 0 )
			{
				Util.EnableGroup( "cpdefense", TEAM.AXIS );
			}
		}

		Util.MapDebugPrint( "Command_Post_Destroyed" );
	},

	Main_Entrance_Destroyed = function()
	{
		Map.MainDoorStatus = 1;

		Util.DisableGoal( "CHECKPOINT.*" );

		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"ATTACK_Main_Door_.*",
			"PLANT_Main_Entrance",
			"PLANT_Bunker_MG_Nest",
			"PLANT_Axis_Road_MG_Nest",
		});

		// Axis goals
		Map.ShiftAxisToParts();

		// set the spawns
		Util.ChangeSpawnForRole( TEAM.AXIS, ROLE.DEFENDER2, 4 );
		Util.ChangeSpawnForRole( TEAM.AXIS, ROLE.DEFENDER1, 5 );

		sleep(0.1);
		Wp.CheckBlockable();

		// Allied goals
		Util.SetMaxUsersInProgress( 8, "FLAG_.*" );
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"ATTACK_Radar_.*",
			"FLAG_radarbox1",
			"FLAG_radarbox2",
			"PLANT_Axis_Watchto.*MG_Nest",
		});

		Util.MapDebugPrint( "Main_Entrance_Destroyed" );
	},

	Planted_Main = function()
	{
		Map.MainDyno += 1;

		if ( !Map.AxisShiftedToParts ) {
			SetAvailableMapGoals( TEAM.AXIS, true, "DEFEND_rMainDefuseAssist.*" );
		}

		Util.MapDebugPrint( "Planted_Main" );
	},

	Defused_Main = function()
	{
		Map.MainDyno -= 1;

		if ( Map.MainDyno < 1 ) {
			SetAvailableMapGoals( TEAM.AXIS, false, "DEFEND_rMainDefuseAssist.*" );
		}

		Util.MapDebugPrint( "Defused_Main" );
	},

	// called from Side_Entrance_Destroyed and Main_Entrance_Destroyed
	ShiftAxisToParts = function()
	{
		SetAvailableMapGoals( TEAM.AXIS, false, {
			"DEFEND_rMainDefuseAssist.*",
			"DEFEND_rSideDefuseAssist.*",
		});

		if (Map.AxisShiftedToParts) {
			return;
		}
		Map.AxisShiftedToParts = true;

		Util.DisableGroup( "eastbunker", TEAM.AXIS );
		Util.DisableGroup( "westbunker", TEAM.AXIS );

		SetAvailableMapGoals( TEAM.AXIS, false, "DEFEND_rBunkerPatrol.*" );

		// don't bother with defuses
		SetGoalPriority( "DEFUSE_Main_Entrance.*", 0.0, TEAM.AXIS, CLASS.ENGINEER, true );
		SetGoalPriority( "DEFUSE_Side_Entrance.*", 0.0, TEAM.AXIS, CLASS.ENGINEER, true );
		SetAvailableMapGoals( TEAM.AXIS, false, { "DEFUSE_Main.*", "DEFUSE_Side.*", }, true);

		if ( Map.CPStatus == 0 && Map.EastPartsStatus < 2 ) {
			SetAvailableMapGoals( TEAM.AXIS, true, "PLANTMINE_rBunkerEast[23]" );
		}

		Map.Parts_Changed();

		SetAvailableMapGoals( TEAM.AXIS, true, {
			"DEFEND_rPartsPatrol.*",
			"AMMOCAB_objhacab3",
			"HEALTHCAB_objhacab4",
		});
	},

	Side_Entrance_Destroyed = function()
	{
		Map.SideDoorStatus = 1;

		sleep(0.1);
		Wp.CheckBlockable();

		// let allies build it now
		ClearGoalRole( "BUILD_Command_Post", ROLE.DEFENDER3 );

		if ( Map.CPStatus == 0 ) {
			Util.EnableGoal("ROUTE_cpassist");
		}
		Util.EnableGoal("ROUTE_cproute");

		// Allied goals
		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"ATTACK_Side_Door_.*",
		});
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"BUILD_Command_Post",
			"PLANT_Command_Post",
		});

		if (!Map.MainDoorStatus) {
			Util.SetMaxUsersInProgress( 1, "FLAG_.*" );
			SetAvailableMapGoals( TEAM.ALLIES, true, "FLAG_.*" );
		}

		// Axis goals
		Map.ShiftAxisToParts();
		if ( Map.CPStatus == 0 && Map.EastPartsStatus == 0 ) {
			Util.EnableGroup( "cpdefense", TEAM.AXIS );
		}
		if (!Map.MainDoorStatus) {
			SetGoalPriority( "CHECKPOINT.*", 0.6, TEAM.AXIS );
		}

		Util.MapDebugPrint( "Side_Entrance_Destroyed" );
	},

	Planted_Side = function()
	{
		Map.SideDyno += 1;

		if ( !Map.AxisShiftedToParts ) {
			SetAvailableMapGoals( TEAM.AXIS, true, "DEFEND_rSideDefuseAssist.*" );
		}

		Util.MapDebugPrint( "Planted_Side" );
	},

	Defused_Side = function()
	{
		Map.SideDyno -= 1;

		if ( Map.SideDyno < 1 ) {
			SetAvailableMapGoals( TEAM.AXIS, false, "DEFEND_rSideDefuseAssist.*" );
		}

		Util.MapDebugPrint( "Defused_Side" );
	},

	Parts_Changed = function()
	{
		// truck
		carry = ( Map.EastPartsStatus == 1 || Map.WestPartsStatus == 1);
		SetAvailableMapGoals( TEAM.ALLIES, carry || !Map.MainDoorStatus, "ATTACK_Main_Door_.*" );
		if (carry) {
			Util.EnableGroup( "rdeliver", TEAM.AXIS );
		}
		else {
			Util.DisableGroup( "rdeliver", TEAM.AXIS );
		}

		// west
		if ( Map.WestPartsStatus == 0) {
			Util.EnableGroup( "westparts", TEAM.AXIS );
		}
		else if (carry) {
			Util.DisableGroup( "westparts", TEAM.AXIS );
		}
		else {
			SetAvailableMapGoals( TEAM.AXIS, true, {
				"DEFEND_rWestParts.*",
				"CALLARTILLERY_rWestParts.*",
				"ARTILLERY_S_rWestParts.*",
			});
		}

		// east
		if ( Map.EastPartsStatus == 0) {
			Util.EnableGroup( "eastparts", TEAM.AXIS );
		}
		else if (carry) {
			Util.DisableGroup( "eastparts", TEAM.AXIS );
		}
		else {
			SetAvailableMapGoals( TEAM.AXIS, true, {
				"DEFEND_rEastParts.*",
				"CALLARTILLERY_rEastParts.*",
				"ARTILLERY_S_rEastParts.*",
			});
		}
	},

	West_Parts_Taken = function()
	{
		Map.WestPartsStatus = 1;
		Map.Parts_Changed();

		Util.MapDebugPrint( "radarbox1_Taken" );
	},

	West_Parts_Returned = function()
	{
		Map.WestPartsStatus = 0;
		Map.Parts_Changed();

		Util.MapDebugPrint( "radarbox1_Returned" );
	},

	West_Radar_Dropoff_Captured = function()
	{
		Map.WestPartsStatus = 2;
		Map.Parts_Changed();

		// add more focus to east
		Util.ClearRoleForGroup("eastparts", ROLE.DEFENDER1);
		SetGoalPriority( "DEFEND_rEastParts.*", 0.65, TEAM.AXIS );

		Util.MapDebugPrint( "radarbox1_Radar_Dropoff_Captured" );
	},

	East_Parts_Taken = function()
	{
		Map.EastPartsStatus = 1;
		Map.Parts_Changed();
		Util.DisableGroup( "cpdefense", TEAM.AXIS );

		Util.MapDebugPrint( "radarbox2_Taken" );
	},

	East_Parts_Returned = function()
	{
		Map.EastPartsStatus = 0;
		Map.Parts_Changed();
		if ( Map.CPStatus == 0 && Map.SideDoorStatus == 1 ) {
			Util.EnableGroup( "cpdefense", TEAM.AXIS );
		}
		Util.MapDebugPrint( "radarbox2_Returned" );
	},

	East_Radar_Dropoff_Captured = function()
	{
		Map.EastPartsStatus = 2;
		Map.Parts_Changed();

		// add more focus to west
		Util.ClearRoleForGroup("westparts", ROLE.DEFENDER2);
		SetGoalPriority( "DEFEND_rWestParts.*", 0.65, TEAM.AXIS );

		Util.MapDebugPrint( "radarbox2_Radar_Dropoff_Captured" );
	},

	roadbunker_Axis_Captured = function()
	{
		SetAvailableMapGoals( TEAM.AXIS, Map.MainDyno > 0, "DEFEND_rMainDefuseAssist.*" );
		SetAvailableMapGoals( TEAM.AXIS, Map.SideDyno > 0, "DEFEND_rSideDefuseAssist.*" );

		Util.MapDebugPrint( "roadbunker_Axis_Captured" );
	},

	roadbunker_Allies_Captured = function()
	{
		if ( !Map.AxisShiftedToParts ) {
			SetAvailableMapGoals( TEAM.AXIS, true, {
				"DEFEND_rMainDefuseAssist.*",
				"DEFEND_rSideDefuseAssist.*",
			});
		}
		Util.MapDebugPrint( "roadbunker_Allies_Captured" );
	},
};

global OnMapLoad = function()
{
	OnTrigger( "The Axis Road MG Nest has been constructed.", Map.Axis_Road_MG_Nest_Built );
	OnTrigger( "The Axis Watchtower MG Nest has been constructed.", Map.Axis_Watchtower_MG_Nest_Built );
	OnTrigger( "The Bunker MG Nest has been constructed.", Map.Bunker_MG_Nest_Built );
	OnTrigger( "Allied Command Post constructed. Charge speed increased!", Map.Allied_Command_Post_Built );
	OnTrigger( "Axis Command Post constructed. Charge speed increased!", Map.Axis_Command_Post_Built );
	OnTrigger( "The Axis Road MG Nest has been destroyed.", Map.Axis_Road_MG_Nest_Destroyed );
	OnTrigger( "The Axis Watchtower MG Nest has been destroyed.", Map.Axis_Watchtower_MG_Nest_Destroyed );
	OnTrigger( "The Bunker MG Nest has been destroyed.", Map.Bunker_MG_Nest_Destroyed );
	OnTrigger( "Axis team has destroyed the Allied Command Post!", Map.Command_Post_Destroyed );
	OnTrigger( "Allied team has destroyed the Axis Command Post!", Map.Command_Post_Destroyed );
	OnTrigger( "Allies have breached the Main Entrance and secured the Forward Bunker!", Map.Main_Entrance_Destroyed );
	OnTrigger( "Allies have breached the Side Entrance!", Map.Side_Entrance_Destroyed );
	OnTrigger( "Allies have stolen the West Radar Parts!", Map.West_Parts_Taken );
	OnTrigger( "Allies have stolen the East Radar Parts!", Map.East_Parts_Taken );
	OnTrigger( "Allies have secured the West Radar Parts!", Map.West_Radar_Dropoff_Captured );
	OnTrigger( "Allies have secured the East Radar Parts!", Map.East_Radar_Dropoff_Captured );
	OnTrigger( "Allies capture the Forward Bunker!", Map.roadbunker_Allies_Captured );
	OnTrigger( "Axis reclaim the Forward Bunker!", Map.roadbunker_Axis_Captured );
	OnTrigger( "Planted at the Main Entrance.", Map.Planted_Main );
	OnTrigger( "Defused at the Main Entrance.", Map.Defused_Main );
	OnTrigger( "Planted at the Side Entrance.", Map.Planted_Side );
	OnTrigger( "Defused at the Side Entrance.", Map.Defused_Side );
	OnTrigger( "Flag returned radarbox1!", Map.West_Parts_Returned );
	OnTrigger( "Flag returned radarbox2!", Map.East_Parts_Returned );

	// Max users per goal
	Util.SetMaxUsers( 4, "CHECKPOINT_roadbunker" );
	Util.SetMaxUsers( 1, {"DEFEND.*", "MOUNTMG42.*"} );
	Util.SetMaxUsersInProgress( 4, {"DEFEND_rSideDefuseAssist.*", "DEFEND_rMainDefuseAssist.*"} );
	Util.SetMaxUsersInProgress( 2, {"DEFEND_rBunkerPatrol.*", "DEFEND_rPartsPatrol.*"} );
	Util.SetMaxUsers( 2, "DEFEND_rDeliver.*" );

	SetMapGoalProperties( "ATTACK_.*", {MinCampTime=10, MaxCampTime=30});
	SetMapGoalProperties( "DEFEND_.*", {MinCampTime=20, MaxCampTime=40});
	SetMapGoalProperties( "DEFEND_rBunkerPatrol.*", {MinCampTime=2, MaxCampTime=3});
	SetMapGoalProperties( "DEFEND_rPartsPatrol.*", {MinCampTime=2, MaxCampTime=3});
	SetMapGoalProperties( "MOUNTMG42_.*", {MinCampTime=9999, MaxCampTime=9999});

	SetGoalPriority( "PLANT_Command_Post", 0.5, 0, CLASS.ENGINEER );
	SetGoalPriority( "PLANT_Command_Post", 0.9, 0, CLASS.COVERTOPS );

	// Allied goals
	SetGoalPriority( "ATTACK_Main_Door_.*", 0.51, TEAM.ALLIES, CLASS.ENGINEER );
	SetGoalPriority( "PLANT_Axis_Road_MG_Nest", 0.5, TEAM.ALLIES, CLASS.ENGINEER );
	SetGoalPriority( "PLANT_Axis_Watchto.*MG_Nest", 0.5, TEAM.ALLIES, CLASS.ENGINEER );
	SetGoalPriority( "PLANT_Bunker_MG_Nest", 0.5, TEAM.ALLIES, CLASS.ENGINEER );

	// Axis goals
	SetGoalPriority( "BUILD_Bunker_MG_Nest", 0.79, TEAM.AXIS );
	SetGoalPriority( "DEFEND_rSideDefuseAssist.*", 0.8, TEAM.AXIS );
	SetGoalPriority( "DEFEND_rMainDefuseAssist.*", 0.8, TEAM.AXIS );
	SetGoalPriority( "DEFEND_rPartsPatrol.*", 0.49, TEAM.AXIS );
	SetGoalPriority( "CHECKPOINT.*", 0.9, TEAM.AXIS ); // always recapture!

	SetGoalRole( "BUILD_Command_Post", ROLE.DEFENDER3 ); //FirstAxisEng

	Util.DisableGoal( ".*", true ); // all but routes

	Util.EnableGoal( { "AMMOCAB_objhacab2", "HEALTHCAB_objhacab1" } );

	SetAvailableMapGoals( TEAM.ALLIES, true, {
		"CAPPOINT_Radar_Dropoff",
		"PLANT_Axis_Road_MG_Nest",
		"PLANT_Bunker_MG_Nest",
		"PLANT_Main_Entrance",
		"PLANT_Side_Entrance",
		"CHECKPOINT_roadbunker",
		"ATTACK_Main_Door_.*",
		"ATTACK_Side_Door_.*",
	});

	Util.EnableGroup( "eastbunker", TEAM.AXIS );
	Util.EnableGroup( "westbunker", TEAM.AXIS );

	SetAvailableMapGoals( TEAM.AXIS, true, {
		"CHECKPOINT_roadbunker",
		"BUILD_Command_Post",
	});

	Util.DisableGoal("ROUTE_cpassist");
	Util.DisableGoal("ROUTE_cproute");

	Util.MapDebugPrint( "OnMapLoad" );
};

global OnBotJoin = function( bot )
{
	bot.MaxViewDistance = 2500;
	bot.TargetBreakableDist = 150.0;

	if ( bot.GetTeam() == TEAM.AXIS ) {
		if ( !Map.FirstAxisEng ) {
			bot.SetRoles(ROLE.DEFENDER3, ROLE.DEFENDER1);
			bot.crucialClass = CLASS.ENGINEER;
			bot.ChangeClass(CLASS.ENGINEER);
			bot.ChangeSpawnPoint(5); // cs: will not work on a map_restart
			Map.FirstAxisEng = bot;
		}
		else {
			bot.ChangeSpawnPoint(3);
		}
	}
};

global InitializeRoutes = function()
{
	MapRoutes =
	{
		CHECKPOINT_roadbunker =
		{
			ROUTE_AllySpawn =
			{
				ROUTE_tunnel =
				{
					ROUTE_hill =
					{
						ROUTE_flagside = { Weight = 2, },
						ROUTE_flagroad =
						{
							ROUTE_flagroad2 = { ROUTE_flagfar = {}, },
						},
					},
				 },
				ROUTE_allyfront =
				{
					Weight = 2,
					ROUTE_flagmain = { Weight = 2, },
					ROUTE_flagside = {},
					ROUTE_flagroad = {},
				},
				ROUTE_flagside = {},
			},
		},
		PLANT_Main_Entrance =
		{
			ROUTE_AllySpawn =
			{
				ROUTE_tunnel =
				{
					ROUTE_hill =
					{
						ROUTE_flagroad =
						{
							ROUTE_flagroad2 = {},
						},
					},
				 },

			},
		},
		FLAG_radarbox1 =
		{
			ROUTE_FlagSpawn =
			{
				ROUTE_maincentral =
				{
					ROUTE_mainflank =
					{
						ROUTE_mainflank2 = {},
					},
				},
				ROUTE_mainright = { ROUTE_mainright2 = {}, },
				ROUTE_cpassist = { Weight = 2, },
			},
			ROUTE_CpSpawn =
			{
				ROUTE_tincorner =
				{
					ROUTE_secorner = { ROUTE_swcorner = {}, },
				},
				ROUTE_mainflank = {},
				ROUTE_bridgehill = { ROUTE_bridge = {}, },
			},
		},
		FLAG_radarbox2 =
		{
			ROUTE_FlagSpawn =
			{
				ROUTE_maincentral = { Weight = 2, },
				ROUTE_mainright2 =
				{
					ROUTE_swcorner = { ROUTE_secorner = {}, },
				},
				ROUTE_cpassist = { Weight = 2, },
			},
			ROUTE_CpSpawn =
			{
				ROUTE_tincorner = { Weight = 2, },
				ROUTE_eastmid = {},
			},
		},
		CAPPOINT_Radar_Dropoff =
		{
			ROUTE_East_Radar =
			{
				ROUTE_cproute =
				{
					ROUTE_flagroute = {},
				},
			},

		},
	};
	MapRoutes["DEFEND_rEastParts.*"] =
	{
		ROUTE_AxisSpawn1 =
		{
			ROUTE_eastpatrol1 = {},
			ROUTE_eastpatrol2 = {},
		},
		ROUTE_AxisSpawn2 =
		{
			ROUTE_gateroute = {},
			ROUTE_westpatrol1 = {},
		},
	};
	MapRoutes["DEFEND_rWestParts.*"] =
	{
		ROUTE_AxisSpawn1 =
		{
			ROUTE_maincentral = {},
			ROUTE_westpatrol1 = {},
			ROUTE_westpatrol2 = {},
		},
	};

	Util.Routes(MapRoutes);
};
