//==========================================================================================
//
//	eltz_beta1.gm
//
//	Who	When		What
//------------------------------------------------------------------------------------------
//	palota	17 August 2010	Initial Script
//	palota	5 September 2010	paththrough navigation
//	palota	23 October 2010	MOBILEMG42, ATTACK_cp, DEFEND goals availability
//
//==========================================================================================
//

global Map =
{
	Debug = 0,
	elevatorPos = 4,
	objTaken = false,

	Switches =
	{
		zeppelingate =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "zeppelingate",
			Wait = function()
			{
				sleep(2.5);
				return true;
			}
		},
		zeppelingate_axis =
		{
			Enabled = false,
			Priority = 0.65,
			WaypointName = "zeppelingate",
			LimitBots = 1,
			LimitTeam = (1<<TEAM.AXIS),
			LimitDistance = 3300,
		},
		elevator_down_call =
		{
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_down_call",
			AimPosition = Vector3(-4311,2325,1086),
			ExitConditions =
			{
				someFunc = function(bot){
					while(Map.elevatorPos==4 || Map.elevatorPos==1 || Map.elevatorPos==2){
						sleep(0.5);
					}
					return false;
				}
			},
		},
		elevator_down_in =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "elevator_down_in",
			AimPosition = Vector3(-4111,2400,1086),
			Wait = function()
			{
				sleep(8);
				return true;
			}
		},
		elevator_up_call =
		{
			Enabled = true,
			Priority = 0,
			WaypointName = "elevator_up_call",
			AimPosition = Vector3(-4080.9,2475,2214),
			ExitConditions =
			{
				someFunc = function(bot){
					while(Map.elevatorPos==1 || Map.elevatorPos==4 || Map.elevatorPos==5){
						sleep(0.5);
					}
					return false;
				}
			},
		},
		elevator_up_in =
		{
			Enabled = false,
			Priority = 0,
			WaypointName = "elevator_up_in",
			AimPosition = Vector3(-4272.9,2400,2214),
			Wait = function()
			{
				sleep(8);
				return true;
			}
		},
	},

	NavDoor = function(_this)
	{
		wpinfo = _this.navigation.wpinfo;
		if(wpinfo==null)
		{
			wpinfo = Util.WpNameInfo(_this.CurrentNavigation);
			_this.navigation.wpinfo = wpinfo;
		}
		pos = wpinfo.position;
		vec = wpinfo.facing.Normalize();
		pos1 = pos - vec * 50;
		pos1 = Vector3(pos1.x, pos1.y, pos.z);
		pos2 = pos + vec * 140;
		pos2 = Vector3(pos2.x, pos2.y, pos.z);

		for(i=0; i<4; i+=1)
		{
			//Util.MapDebugPrint("goto door");
			if(_this.Goto(pos) == EVENT.PATH_FAILED )
			{
				//Util.MapDebugPrint("goto door failed");
				return;
			}
			_this.AddAimRequest(Priority.High, "facing", wpinfo.facing);
			tr = TraceLine(pos, pos2, null, TRACE.SOLID, 0, true);
			if(tr.fraction == 1)
			{
				//Util.MapDebugPrint("go through door");
				_this.Bot.MoveTowards(pos2);
				sleep(0.6);
				break;
			}
			sleep(0.1);
			//Util.MapDebugPrint("open");
			_this.Bot.PressButton(BTN.USE);
			_this.Bot.MoveTowards(pos1);
			//wait while door opens
			sleep(1);
		}
	},

	Navigation =
	{
		axis_door1 =
		{
			navigate = function(_this) { Map.NavDoor(_this); },
		},
		axis_door2 =
		{
			navigate = function(_this) { Map.NavDoor(_this); },
		},
		allied_door1 =
		{
			navigate = function(_this) { Map.NavDoor(_this); },
		},
		teleporter =
		{
			navigate = function(_this)
			{
				sleep(2);
				Util.MapDebugPrint("teleporter");
				_this.Goto(_this.Bot.GetPosition());
				sleep(0.5);
			},
		},
	},

	Tunnel_Entrance_Destroyed = function( trigger )
	{
		SetAvailableMapGoals(TEAM.ALLIES, false, "ATTACK_tunnel.*");
		Util.EnableGoal("ROUTE_tunnel_entrance");
		Util.MapDebugPrint( "Tunnel_Entrance_Destroyed" );
	},

	Generator_Built = function( trigger )
	{
		//SetAvailableMapGoals(TEAM.ALLIES, true, "ATTACK_generator.*");
		Util.DisableGoal("ROUTE_west_gate");
		Util.DisableGoal("ROUTE_east_gate");
		Util.MapDebugPrint( "Generator_Built" );
	},

	Generator_Destroyed = function( trigger )
	{
		//SetAvailableMapGoals(TEAM.ALLIES, false, "ATTACK_generator.*");
		Util.EnableGoal("ROUTE_west_gate");
		Util.EnableGoal("ROUTE_east_gate");
		Util.MapDebugPrint( "Generator_Destroyed" );
	},

	SetDefend = function()
	{
		SetAvailableMapGoals(TEAM.AXIS, Map.commandPostDestroyed && !Map.objTaken, {
			"DEFEND_cp.*",
			"TRIPMINE_church.*",
			"DEFEND_village.*",
			"DEFEND_tunnel_entrance.*",
		});
		SetAvailableMapGoals(TEAM.AXIS, !Map.commandPostDestroyed && !Map.objTaken, {
			"DEFEND_crystals.*",
			"TRIPMINE_crystals.*",
		});
		SetAvailableMapGoals(TEAM.AXIS, !Map.objTaken, "DEFEND_generator.*");
		SetAvailableMapGoals(TEAM.AXIS, Map.objTaken, "DEFEND_zeppelin.*");
	},

	SetCommandPost = function( destroyed )
	{
		Map.commandPostDestroyed = destroyed;
		Map.SetDefend();
		SetAvailableMapGoals(TEAM.AXIS, destroyed, {
			"SNIPE_castle_tower",
			"PLANTMINE_cp.*",
			"MOBILEMG42_.*",
		});
		SetAvailableMapGoals(TEAM.ALLIES, destroyed, "ATTACK_cp.*");
		//SetAvailableMapGoals(TEAM.ALLIES, destroyed, "SNIPE_village.*");
		if (destroyed){ m=30; }else{ m=60; }
		Util.SetPercentInProgress(m, "FLAG_crystals_obj");
	},

	Allied_Command_Post_Built = function( trigger )
	{
		Map.SetCommandPost(false);
		Util.MapDebugPrint( "Allied_Command_Post_Built" );
	},

	Allied_Command_Post_Destroyed = function( trigger )
	{
		Map.SetCommandPost(true);
		Util.MapDebugPrint( "Allied_Command_Post_Destroyed" );
	},

	SetZeppelin = function(taken)
	{
		Map.objTaken = taken;
		Map.SetDefend();
		SetAvailableMapGoals(TEAM.AXIS, taken, "SNIPE_.*zeppelin.*");
		SetAvailableMapGoals(TEAM.ALLIES, taken, "ATTACK.*zeppelin.*");
	},

	crystals_obj_Taken = function( trigger )
	{
		Map.SetZeppelin(true);
		Util.MapDebugPrint( "crystals_obj_Taken" );
	},

	crystals_obj_Returned = function( trigger )
	{
		Map.SetZeppelin(false);
		Util.MapDebugPrint( "crystals_obj_Returned" );
	},

	zeppelin_gate_trigger = function( trigger )
	{
		closed = ToVector(trigger.Action).z > 0;
		Map.Switches.zeppelingate_axis.Enabled = !closed;
		if(closed){ sleep(3); }
		Map.Switches.zeppelingate.Enabled = closed;
	},

	lift_trigger = function( trigger )
	{
		if (ToVector(trigger.Action).z > 0)
		{
			Util.MapDebugPrint("elevator is moving up", true);
			Map.elevatorPos=1;
			Map.Switches.elevator_down_in.Enabled = false;
			Map.Switches.elevator_down_call.Enabled = true;
			sleep(8);
			Map.Switches.elevator_up_call.Enabled = false;
			Map.Switches.elevator_up_in.Enabled = true;
			Map.elevatorPos=2;
			sleep(2);
			Map.elevatorPos=3;
		}else{
			Util.MapDebugPrint("elevator is moving down", true);
			Map.elevatorPos=4;
			Map.Switches.elevator_up_in.Enabled = false;
			Map.Switches.elevator_up_call.Enabled = true;
			sleep(8);
			Map.Switches.elevator_down_call.Enabled = false;
			Map.Switches.elevator_down_in.Enabled = true;
			Map.elevatorPos=5;
			sleep(2);
			Map.elevatorPos=6;
		}
	},

	Zeppelin_Landed = function( trigger )
	{
		if (ToVector(trigger.Action).z < 0)
		{
			SetAvailableMapGoals(TEAM.ALLIES, true, {
				"FLAG_crystals_obj",
				"CAPPOINT_.*",
			});
			Util.EnableGoal("ROUTE_nach_teleport.*");
			Util.MapDebugPrint( "Zeppelin_Landed" );
		}
	},
};

global OnMapLoad = function()
{
	// Register callback functions
	OnTrigger( "Allies destroyed the Tunnel Grate", Map.Tunnel_Entrance_Destroyed );
	OnTrigger( "Axis has constructed the Generator! Gates are now Closed!", Map.Generator_Built );
	OnTrigger( "The Generator has been Destroyed! Castle Gates are now Open!!!", Map.Generator_Destroyed );
	OnTrigger( "Allied Command Post constructed. Charge speed increased!", Map.Allied_Command_Post_Built );
	OnTrigger( "Axis team has destroyed the Allied Command Post!", Map.Allied_Command_Post_Destroyed );
	OnTrigger( "allies have stolen the Crystals!", Map.crystals_obj_Taken );
	OnTrigger( "Flag returned crystals_obj!", Map.crystals_obj_Returned );
	OnTrigger( "rocdoor_lever_goto", Map.zeppelin_gate_trigger );
	OnTrigger( "lift_goto", Map.lift_trigger );
	OnTrigger( "zep_clip_goto", Map.Zeppelin_Landed );

	Util.DisableGoal(".*zeppelin.*", true);
	Util.DisableGoal("FLAG_crystals_obj");
	Util.DisableGoal("ROUTE_west_gate");
	Util.DisableGoal("ROUTE_east_gate");
	Util.DisableGoal("ROUTE_tunnel_entrance");
	Util.DisableGoal("ROUTE_nach_teleport.*");
	Util.LimitToTeam(TEAM.ALLIES, "ROUTE_crystals");
	Util.LimitToTeam(TEAM.AXIS, "ROUTE_crystals_axis");
	SetAvailableMapGoals(TEAM.AXIS, false, "ATTACK_.*");
	SetAvailableMapGoals(TEAM.ALLIES, false, {
		"DEFEND_.*",
		".*MINE_.*",
		"SNIPE_castle_tower",
	});

	SetGoalPriority("DEFEND_crystals.*", 0.53);
	SetGoalPriority("DEFEND_village.*", 0.53);
	SetGoalPriority("DEFEND_cp4", 0.52);
	SetGoalPriority("DEFEND_zeppelin.*", 0.85);
	SetGoalPriority("SNIPE_.*zeppelin.*", 0.9);
	SetGoalPriority("FLAG.*", 0.86, TEAM.AXIS, 0, true);
	SetGoalPriority("FLAG_crystals_obj", 0.69, TEAM.ALLIES);
	SetGoalPriority("PLANT_Allied_Command_Post", 0.78, TEAM.AXIS, CLASS.ENGINEER);
	SetGoalPriority("PLANTMINE_cp.*", 0.8, TEAM.AXIS, CLASS.ENGINEER);

	// Max users per goal
	Util.SetMaxUsers( 1, "BUILD_.*" );
	Util.SetMaxUsers( 1, "DEFEND_.*" );

	// Camp times
	SetMapGoalProperties( "DEFEND_.*", {mincamptime=30, maxcamptime=80} );
	SetMapGoalProperties( "SNIPE_.*", {mincamptime=250, maxcamptime=350} );
	SetMapGoalProperties( "MOBILE_.*", {mincamptime=200, maxcamptime=300} );

	MapRoutes =
	{
		BUILD_Allied_Command_Post = {
			ROUTE_allies = {
				ROUTE_village_east = { Weight=2 },
				ROUTE_village_statue = { ROUTE_north_east_cave = {}},
				ROUTE_village_statue2 = {  Weight=0.5, ROUTE_village_bridge = {}},
				ROUTE_village_west = { Weight=1.5 },
				ROUTE_waterfall = { Weight=1.5 },
			},
		},
		DEFEND_cp1 = {
			ROUTE_axis1 = {
				ROUTE_nach_dorf = { Weight=2 },
				ROUTE_nach_dorf2 = {},
				ROUTE_nach_teleport1 = { Weight = 2,
					ROUTE_crystals_west1 = { ROUTE_caves_entrance = {} },
					ROUTE_crystals_west2 = { ROUTE_caves_entrance = {} },
				},
				ROUTE_nach_teleport2 = { Weight = 2,
					ROUTE_crystals_north2 = { ROUTE_caves_entrance = {} },
					ROUTE_crystals_north3 = { ROUTE_caves_entrance = {} },
				},
			},
			ROUTE_crystals_axis = {
				ROUTE_east_gate = { Weight = 2 },
				ROUTE_west_gate = { Weight = 4 },
				ROUTE_tunnel = { Weight = 2 },
				ROUTE_crystals_north = { ROUTE_caves_entrance = {}},
				ROUTE_crystals_west1 = {},
				ROUTE_crystals_west2 = {},
			},
		},
		MOBILEMG42_tunnel1 = {
			ROUTE_axis1 = {
				ROUTE_tunnel = {},
			}
		},
		FLAG_crystals_obj = {
			ROUTE_command_post = {
				ROUTE_east_gate = { Weight = 2 },
				ROUTE_west_gate = { Weight = 2 },
				ROUTE_tunnel_entrance = {  ROUTE_tunnel = {} },
				ROUTE_caves_entrance = {
					ROUTE_crystals_north1 = {},
					ROUTE_crystals_north2 = {},
					ROUTE_crystals_north3 = {},
					ROUTE_crystals_west1 = { Weight=1.5 },
					ROUTE_crystals_west2 = { Weight=1.5 },
				},
			}
		},
		CAPPOINT_zeppelin = {
			ROUTE_crystals = {
				ROUTE_west_gate = { Weight = 5 },
				ROUTE_caves_entrance = { Weight = 2 },
				ROUTE_zeppelin_gate = {},
				ROUTE_zeppelin_above_gate = {},
			}
		},
	};
	MapRoutes.CAPPOINT_zeppelin.ROUTE_teleporter = MapRoutes.CAPPOINT_zeppelin.ROUTE_crystals;
	MapRoutes.FLAG_crystals_obj.ROUTE_allies = MapRoutes.BUILD_Allied_Command_Post.ROUTE_allies;
	MapRoutes.ATTACK_tunnel1 = MapRoutes.BUILD_Allied_Command_Post;
	MapRoutes.ATTACK_tunnel2 = MapRoutes.ATTACK_tunnel1;
	MapRoutes.PLANT_Generator = MapRoutes.BUILD_Allied_Command_Post;
	MapRoutes.ATTACK_generator1 = MapRoutes.PLANT_Generator;
	MapRoutes.ATTACK_generator2 = MapRoutes.ATTACK_generator1;
	MapRoutes.ATTACK_cp1 = MapRoutes.BUILD_Allied_Command_Post;
	MapRoutes.ATTACK_cp2 = MapRoutes.ATTACK_cp1;
	MapRoutes.DEFEND_cp1.ROUTE_axis2 = MapRoutes.DEFEND_cp1.ROUTE_axis1;
	MapRoutes.DEFEND_cp2 = MapRoutes.DEFEND_cp1;
	MapRoutes.DEFEND_cp3 = MapRoutes.DEFEND_cp1;
	MapRoutes.DEFEND_cp4 = MapRoutes.DEFEND_cp1;
	MapRoutes.DEFEND_cp5 = MapRoutes.DEFEND_cp1;
	MapRoutes.DEFEND_cp6 = MapRoutes.DEFEND_cp1;
	MapRoutes.DEFEND_generator1 = MapRoutes.DEFEND_cp1;
	MapRoutes.MOBILEMG42_tunnel1.ROUTE_axis2 = MapRoutes.MOBILEMG42_tunnel1.ROUTE_axis1;
	MapRoutes.MOBILEMG42_tunnel2 = MapRoutes.MOBILEMG42_tunnel1;

	Util.Routes(MapRoutes);

	Util.UpdateSwitchData();
	Map.SetCommandPost(true); //must be called after UpdateSwitchData, because there is yield in SetPercentInProgress

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

global OnBotJoin = function( bot )
{
	bot.TargetBreakableDist = 80.0;
};
