//==========================================================================================
//
//  V-2 Factory - v2_factory.gm
//
//  Who         When            What
//------------------------------------------------------------------------------------------
//  Tardis 	    22/04/2015	  Fixes to MOVER_coal_car - Axis 		
//  Mateos      02/03/2015      Axis were trying to escort the Truck all along the map...
//  palota      19/11/2014      Last fixes from palota for all waypoints
//  crapshoot   17/11/2011      Last fixes regarding goals for all waypoints
//  IRATA[*]    27/11/2010      Cleanup
//  crapshoot   02/07/2010      Initial 0.8 commit from 0.71
//
//==========================================================================================
//

// cs: this map needs routing. camptimes?

/*
 * Mateos:
 * Watched a bit the waypoints and goals, seems to need a review about:
 * - Routing
 * - MGs aiming
 * - Script cleanup
 * - Make the bots wait a bit at their camping goals...
 */

global Map =
{
	// Set Talk to false if you don't want the bots to use voice chat
	Talk = true,
	Mines = true,

	Movers =
	{
		// Retain these movers
		"MOVER_truck",
		"MOVER_coal_car",
	},

	// For build position of the Train
	UpdateTrainBuild = function()
	{
		newPos = GetEntityWorldSpace(GetGoal("MOVER_coal_car").GetEntity(),Vector3(8.272,274.457,10.900));
		Util.SetGoalPosition(newPos.x, newPos.y, newPos.z, "BUILD_Train_Engine");
	},

	UpdateTrainPlant = function()
	{
		if(!Map.TrainGoal)
        {
            Map.TrainGoal = GetGoal("MOVER_coal_car");
        }

		Map.PlantPointOffset = Vector3(100,340,10);

		if ( !Map.TrainGoal )
		{
			Util.MapDebugPrint( "UpdateTrainPlant: Invalid Goalname!" );
			return;
		}

		// The main loop that updates the plant position
		while(1)
		{
			moverPos = Map.TrainGoal.GetPosition();

			// Update the position only if the Train has moved
			if ( moverPos != Map.TrainPosition )
			{
				Map.TrainPosition = moverPos;
				newPlantPos = moverPos + Map.PlantPointOffset;
				Util.SetGoalPosition(newPlantPos.x, newPlantPos.y, newPlantPos.z, "PLANT_Train_Engine");

				// Toggle availability so they repath
				SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Train_Engine" );
				sleep(0.5);
				SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Train_Engine" );
			}

			sleep(2);
			//Util.MapDebugPrint( "mover pos.: " + newPlantPos );
		}
	},

	Navigation =
	{
		quickjump =
		{
			// Better response time than nav flags
			navigate = function(_this)
			{
				_this.Bot.PressButton(BTN.JUMP);
				yield();
			},
		},
	},

	TruckOutOfShack = function( trigger )
	{
		// Enable all construction offsets
		ETUtil.SetExcludeIndexes( "BUILD_Truck", {} );
		ETUtil.SetExcludeIndexes( "ESCORT_truck", {0,1} );

		// Set up a new positional trigger for the truck
		Util.OnTriggerPosition("MOVER_truck", "bridge_trigger", 150, Map.TruckAtBridge);
		Util.MapDebugPrint( "TruckOutOfShack" );
	},

	TruckAtBridge = function( trigger )
	{
		ETUtil.SetExcludeIndexes( "BUILD_Truck", { 0, 1 } );

		// Enable bridge construction
		SetAvailableMapGoals(TEAM.ALLIES, true, "BUILD_Pontoon_Bridge");
		SetAvailableMapGoals(TEAM.ALLIES, false, {
			"ATTACK_allies_9",
			"ATTACK_allies_10",
			"ATTACK_allies_11",
			"ATTACK_allies_12",
			"ESCORT_truck",
		});

		// Set up a new positional trigger for the truck
		Util.OnTriggerPosition("MOVER_truck", "bridge_trigger2", 150, Map.TruckOnBridge);

        Util.MapDebugPrint( "TruckAtBridge" );
	},

	TruckOnBridge = function( trigger )
	{
		// Enable all construction offsets
		ETUtil.SetExcludeIndexes( "BUILD_Truck", {} );

		// Set up a new positional trigger for the truck
		Util.OnTriggerPosition("MOVER_truck", "compost_trigger", 150, Map.TruckAtCompost);

		Util.MapDebugPrint( "TruckOnBridge" );
	},

	pontoon_bridge_Built = function( trigger )
	{
		SetAvailableMapGoals(TEAM.ALLIES, true, "ESCORT_truck");

        Util.MapDebugPrint( "pontoon_bridge_Built" );
	},

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

	TruckAtCompost = function( trigger )
	{
		SetAvailableMapGoals(TEAM.ALLIES, true, "BUILD_Allied_Command_Post");
		SetAvailableMapGoals(TEAM.ALLIES, false, {
			"BUILD_Truck",
			"ESCORT_truck",
			"MOBILEMORTAR_bridge.*",
		});

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

		// Make Axis bots ignore the Truck from now on
		the_truck = GetGoal("MOVER_truck");
		foreach ( gameId and bot in BotTable )
		{
			bot.IgnoreTarget( the_truck.GetEntity(), 9999 );
		}

		Util.MapDebugPrint( "TruckAtCompost" );
	},

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

	train_construct_Destroyed = function( trigger )
	{
		// Fix the build position
		Map.UpdateTrainBuild();

		Util.MapDebugPrint( "train_construct_Destroyed" );
	},

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

	truck_construct_Destroyed = function( trigger )
	{
		Util.SetPositionGoal( "BUILD_Truck", "MOVER_truck" );
		//Util.SetGoalOffset( 0,20,20, "BUILD_Truck" );

        Util.MapDebugPrint( "truck_construct_Destroyed" );
	},

	allied_cp_build_Built = function( trigger )
	{
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"SNIPE_axis_production.*",
			"DEFEND_axis_production.*",
		});

		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"SNIPE_allies_bridge.*",
			"ATTACK_allies_bridge.*",
		});
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"SNIPE_allies_production.*",
			"ATTACK_allies_production.*",
		});

		Util.MapDebugPrint( "allied_cp_build_Built" );
	},

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

	mgnest_allies1_build_Built = function( trigger )
	{
		Wp.SetWaypointFlag("barn_mg", "closed", false);

        Util.MapDebugPrint( "mgnest_allies1_build_Built" );
	},

	mgnest_allies1_build_Destroyed = function( trigger )
	{
		Wp.SetWaypointFlag("barn_mg", "closed", true);

        Util.MapDebugPrint( "mgnest_allies1_build_Destroyed" );
	},

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

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

	// This is the second (?) major phase, when the rocket is loaded on the train
	v2_assembly_Complete = function( trigger )
	{
		// Fix the build position
		Map.UpdateTrainBuild();

		SetAvailableMapGoals( TEAM.AXIS, false, {
			"ATTACK_.*",
			"BUILD_Ammo_Depot_MG_Nest",
			"DEFEND_.*",
			"MOUNTMG42_Ammo_Depot_MG_Nest",
			"REPAIRMG42_Ammo_Depot_MG_Nest",
			"SNIPE_.*",
		});
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"DEFEND_axis_train.*",
			"SNIPE_axis_train.*",
		});

		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"ATTACK_.*",
			"DEFEND_.*",
            "MOBILEMG42_allies_bridge.*",
			"MOUNTMG42_Barn_MG_Nest",
			"REPAIRMG42_Barn_MG_Nest",
			"SNIPE_.*",
		});
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"ATTACK_allies_train.*",
			"BUILD_Barn_MG_Nest",
			"MOBILEMORTAR_allies_train.*",
			"MOBILEMORTAR_train.*",
			"MOBILEMORTAR_trainbridge.*",   // The one above includes it, isn't it?
			"SNIPE_allies_train.*",
		});

		// Train Bridge MG
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"MOUNTMG42_Train_Bridge_MG_Nest",
			"REPAIRMG42_Train_Bridge_MG_Nest",
			"BUILD_Train_Bridge_MG_Nest",
			"BUILD_Train_Engine",
			"BUILD_Train_Bridge",
		});
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"PLANT_Train_Bridge",
			"PLANT_Tunnel_Support",
		});

		Util.RemoveGoal("PLANT_Pontoon_Bridge");
		Util.RemoveGoal("PLANT_Allied_Command_Post");
		Util.RemoveGoal("PLANT_Liquid_O2_Production_Machines");
		Util.RemoveGoal("PLANT_Liquid_O2_Storage_Tanks");
		Util.RemoveGoal("PLANT_V_2_Assembly_Controls");
		Util.RemoveGoal("BUILD_V_2_Assembly_Controls");
		Util.RemoveGoal("BUILD_Liquid_O2_Storage_Tanks");
		Util.RemoveGoal("BUILD_Liquid_O2_Production_Machines");
		Util.RemoveGoal("BUILD_Pontoon_Bridge");
		Util.RemoveGoal("BUILD_Allied_Command_Post");
		Util.RemoveGoal("BUILD_Truck");

		Util.OnTriggerPosition("MOVER_coal_car", "tunnel_trigger", 200, Map.TrainInTunnel);

		timeLeft = GetGameTimeLeft();
		if (MAP_TALK && Map.Talk && timeLeft>180)
		{
			rand = ETUtil.CountTeam(TEAM.ALLIES) * 2;
			rand2 = ETUtil.CountTeam(TEAM.AXIS) * 2;

            foreach ( gameId and bot in BotTable )
			{
				if (bot.GetTeam() == TEAM.ALLIES && RandInt(1,rand) < 2)
				{
					sleep(1.0);
					bot.SayVoice(VOICE.REINFORCE_OFF);
				}
				else if (bot.GetTeam() == TEAM.ALLIES && RandInt(1,rand) < 2)
				{
					sleep(1.5);
					bot.ExecCommand("vsay_team FTAttack");
				}
				else if (bot.GetTeam() == TEAM.ALLIES && RandInt(0,rand) < 2 && bot.GetClass() != CLASS.ENGINEER)
				{
					sleep(1.2);
					bot.SayVoice(VOICE.DESTROY_VEHICLE);
				}

                if (timeLeft>60 && bot.GetTeam() == TEAM.AXIS && RandInt(0,rand2) < 2)
				{
					sleep(1.0);
					bot.SayVoice(VOICE.REINFORCE_DEF);
				}
				else if (timeLeft>300 && bot.GetTeam() == TEAM.AXIS && RandInt(1,rand2) < 2)
				{
					sleep(2.0);
					bot.SayVoice(VOICE.LETS_GO);
				}
			}
		}

		Util.MapDebugPrint( "v2_assembly_Complete" );
	},

	Factory_Railgate_Open = function(trigger)
	{
		thread(Map.UpdateTrainPlant);

        Util.EnableGoal( "ROUTE_train_gate" );

		Util.MapDebugPrint( "Factory_Railgate_Open", true );
	},

	Rocket_Loaded = function(trigger)
	{
		SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Train_Engine" );

		vel = ToVector(trigger.Action);
		if ( vel.z == 50.01 )
        {
			SetAvailableMapGoals( TEAM.AXIS, true, "RIDE_train" );

			Util.MapDebugPrint( "Rocket_Loaded", true );
		}

	},

	TrainInTunnel = function(trigger)
	{
		SetAvailableMapGoals( TEAM.AXIS, false, {
			"ATTACK_.*",
			"DEFEND_.*",
			"MOUNTMG42_257",
			"REPAIRMG42_257",
			"SNIPE_.*",
		});
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"SNIPE_tunnel.*",
			"ATTACK_tunnel.*",
		});

		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"MOBILEMORTAR_trainbridge.*",
			"SNIPE_.*",
			"DEFEND_.*",
			"ATTACK_.*",
		});
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"SNIPE_tunnel.*",
			"ATTACK_tunnel.*",
		});

		Util.OnTriggerPosition( "MOVER_coal_car", "tunnel_trigger2", 200, Map.TrainOutOfTunnel );

		Util.MapDebugPrint("TrainInTunnel");
	},

	TrainOutOfTunnel = function(trigger)
	{
		SetAvailableMapGoals( TEAM.AXIS, false, {
			"ATTACK_.*",
			"BUILD_Train_Bridge_MG_Nest",
			"DEFEND_.*",
			"MOUNTMG42_Train_Bridge_MG_Nest",
			"REPAIRMG42_Train_Bridge_MG_Nest",
			"SNIPE_.*",
		});
		SetAvailableMapGoals( TEAM.AXIS, true, {
			"ATTACK_after_tunnel.*",
			"SNIPE_after_tunnel.*",
		});

		SetAvailableMapGoals( TEAM.ALLIES, false, {
			"ATTACK_.*",
			"DEFEND_.*",
			"SNIPE_.*",
		});
		SetAvailableMapGoals( TEAM.ALLIES, true, {
			"ATTACK_after_tunnel.*",
			"SNIPE_after_tunnel.*",
		});

		Util.RemoveGoal("PLANT_Tunnel_Support");
		Util.RemoveGoal("BUILD_Tunnel_Support");

		Util.MapDebugPrint("TrainOutOfTunnel");
	},

	AlliesWon = function( trigger )
	{
		ETUtil.WinningChat( TEAM.ALLIES );
		ETUtil.LosingChat( TEAM.AXIS );

        Util.MapDebugPrint("AlliesWon");
	},

	AxisWon = function( trigger )
	{
		ETUtil.WinningChat( TEAM.AXIS );
		ETUtil.LosingChat( TEAM.ALLIES );

		Util.MapDebugPrint("AxisWon");
	},

};

global OnMapLoad = function()
{
	// This region trigger disables bot pushing and combat movement at the axis spawn window
	axisWindow = OnTriggerRegion(AABB(1311.125,-1020.875,-224.875,1580.875,-688.033,-84.646), RegionTrigger.DisableBotPush);

	// *** TRIGGERS ***
	OnTrigger( "The Truck has been repaired", Map.truck_construct_Built );
	OnTrigger( "The Truck has been damaged!", Map.truck_construct_Destroyed );
	OnTrigger( "The Barn MG nest has been constructed", Map.mgnest_allies1_build_Built );
	OnTrigger( "The Barn MG nest has been destroyed", Map.mgnest_allies1_build_Destroyed );
	OnTrigger( "The Allied command post has been constructed", Map.allied_cp_build_Built );
	OnTrigger( "The Allied command post has been destroyed", Map.allied_cp_build_Destroyed );
	OnTrigger( "Allies have built the bridge", Map.pontoon_bridge_Built );
	OnTrigger( "Axis have destroyed part of the bridge", Map.pontoon_bridge_Destroyed );
	OnTrigger( "Axis have laid the train tracks", Map.train_bridge_Built );
	OnTrigger( "Allies have destroyed the Train Bridge", Map.train_bridge_Destroyed );
	OnTrigger( "The Train has been repaired", Map.train_construct_Built );
	OnTrigger( "The Train has been damaged!", Map.train_construct_Destroyed );
	OnTrigger( "V-2 Assembly: Completed", Map.v2_assembly_Complete );
	OnTrigger( "Allies have destroyed all three machines - porduction halted!", Map.AlliesWon );
	OnTrigger( "Axis have delivered the V-2 to safety!", Map.AxisWon );
	OnTrigger( "factory_railgate_right_stop", Map.Factory_Railgate_Open );
	OnTrigger( "crane_hook_goto", Map.Rocket_Loaded );

	// *** VARIOUS ***
	Util.OnTriggerPosition( "MOVER_truck", "shack1", 150, Map.TruckOutOfShack );
	Util.SetPositionGoal( "BUILD_Truck", "MOVER_truck" );
	Util.SetGoalOffset( 0, 0, 200, "PLANT_train_bridge" );
	Util.SetGoalOffset( 0, 0, 150, "PLANT_pontoon_bridge" );
	Util.SetGoalOffset( 0, -20, -50, "PLANT_Liquid_O2_Production_Machines" );
	SetGoalPriority( "PLANT_Train_Engine", 0.0, TEAM.ALLIES, CLASS.ENGINEER );

	Wp.SetWaypointFlag("barn_mg", "closed", true);
	ETUtil.SetExcludeIndexes( "BUILD_Truck", { 2, 3, 4, 5 } );  // Disable offsets 2 through 5
	ETUtil.SetExcludeIndexes( "ESCORT_truck", { 2, 3 } );

	// *** MAX USERS ***
	Util.SetMaxUsers( 2, "RIDE_train" );    // We run against time here ...
	Util.SetMaxUsers( 1, "DEFEND_.*" );
	Util.SetMaxUsers( 1, "MOUNT.*" );
	Util.SetMaxUsers( 1, "MOBILE.*" );
	Util.SetMaxUsers( 2, "BUILD_.*" );
	Util.SetMaxUsersInProgress( 2, "PLANT_.*" );
	Util.SetMaxUsersInUse( 1, "PLANT_.*" );

	SetAvailableMapGoals( 0, false, {
		"ATTACK_.*",
		"DEFEND_.*",
		"SNIPE_.*",
	});

	// *** AXIS GOALS ***
	SetAvailableMapGoals( TEAM.AXIS, true, {
		"DEFEND_axis_bridge.*",
		"SNIPE_axis_bridge.*",
	});
	SetAvailableMapGoals( TEAM.AXIS, false, {
		"BUILD_Barn_MG_Nest",
        "ESCORT_truck",
		"MOBILEMG42_allies_.*",
		"MOBILEMORTAR_.*",
		"MOUNTMG42_Barn_MG_Nest",
		"REPAIRMG42_Barn_MG_Nest",
		// Train Bridge MG - Disabled initially
		"BUILD_Train_Bridge_MG_Nest",
		"REPAIRMG42_Train_Bridge_MG_Nest",
		"MOUNTMG42_Train_Bridge_MG_Nest",
		// Train stuff
		"BUILD_Train_Bridge",
		"BUILD_Train_Engine",
		"RIDE_train",
	});

	// *** ALLIED GOALS ***
	SetAvailableMapGoals( TEAM.ALLIES, true, {
		"ATTACK_allies_bridge.*",
		"SNIPE_allies_bridge.*",
	});
	SetAvailableMapGoals( TEAM.ALLIES, false, {
		"PLANT_Train_Bridge",
		"PLANT_Train_Engine",
		"PLANT_Tunnel_Support",
		"MOUNTMG42_135",
		"REPAIRMG42_135",
		"MOUNTMG42_Ammo_Depot_MG_Nest",
		"REPAIRMG42_Ammo_Depot_MG_Nest",
		"BUILD_Train_Bridge_MG_Nest",
		"REPAIRMG42_Train_Bridge_MG_Nest",
		"MOUNTMG42_Train_Bridge_MG_Nest",
		"MOBILEMORTAR_train.*",
		"MOBILEMORTAR_allies_train.*",
		"RIDE_train",
		// Allied construct goals
		"BUILD_Allied_Command_Post",
		"BUILD_Pontoon_Bridge",
	});

	Util.FixMoverPos("truck", Vec3(1387.000, 3702.500, -355.500), Vec3(1386.000, 3846.000, -410.000));

	Util.MapDebugPrint( "Omni-Bot 0.8x map script for V-2 Factory loaded." );
};

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

global InitializeRoutes = function()
{
	MapRoutes =
	{
		PLANT_Liquid_O2_Production_Machines =
		{
			ROUTE_allied_spawn  =
			{
				ROUTE_tunnel1  =
				{
					ROUTE_hill_center = {},
					ROUTE_hill_left = {},
					ROUTE_hill_right = {},
					ROUTE_train_gate = {},
				},

				ROUTE_tunnel2  =
				{
					ROUTE_hill_center = {},
					ROUTE_hill_left = {},
					ROUTE_hill_right = {},
					ROUTE_train_gate = {},
				},

				ROUTE_axis_cp = {},
			},

			ROUTE_ammo_depot  =
			{
				ROUTE_tunnel2 =
				{
					ROUTE_hill_center = {},
					ROUTE_hill_left = {},
					ROUTE_hill_right = {},
					ROUTE_train_gate = {},
				},

				ROUTE_tunnel1 =
				{
					ROUTE_hill_center = {},
					ROUTE_hill_left = {},
					ROUTE_hill_right = {},
					ROUTE_train_gate = {},
				},
			},
		},

		BUILD_Barn_MG_Nest =
		{
			ROUTE_allied_spawn =
			{
				ROUTE_mg_left = {},
				ROUTE_mg_right = {},
			},
		},

		DEFEND_axis_production1 =
		{
			ROUTE_axis_spawn =
			{
				ROUTE_axis_left = {},
				ROUTE_axis_right = {},
				//ROUTE_axis_right2 = {},
			},
		},
	};

	MapRoutes.PLANT_Train_Bridge_MG_Nest = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.PLANT_V_2_Assembly_Controls = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.PLANT_Liquid_O2_Storage_Tanks = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.ATTACK_allies_production1 = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.ATTACK_allies_production2 = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.ATTACK_allies_production3 = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.ATTACK_allies_production4 = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.ATTACK_allies_production5 = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.ATTACK_allies_production6 = MapRoutes.PLANT_Liquid_O2_Production_Machines;
	MapRoutes.DEFEND_axis_production2 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production3 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production4 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production5 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production6 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production7 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production8 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production9 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production10 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production11 = MapRoutes.DEFEND_axis_production1;
	MapRoutes.DEFEND_axis_production12 = MapRoutes.DEFEND_axis_production1;

	Util.Routes(MapRoutes);

	Util.DisableGoal( "ROUTE_train_gate" );
};
