//======================================================================================
//
//  Nachteinbruch Final - nachteinbruch.gm
//
//  Who         When            What
//--------------------------------------------------------------------------------------
//  Mateos      27 April 2015   Finished.
//  Mateos      ~2010           Everything from scratch.
//
//=======================================================================================

/****************************************************
Path mapping and script by Mateos
Correspondant WAY file size: 48,9 Ko (50 161 octets)
Last Update: 27th April 2016
****************************************************/

global Map =
{
    Debug = 0,  // Please set to zero before distributing your script

    IsAlliedCPBuilt = false,
    IsAmmoStorageGateBuilt = false,
    IsAmmoSupplyDestroyed = false,
    IsMainDoorDestroyed = false,

    Allies_Command_Post_Dyno = 0,
    Ammo_Storage_Gate_Dyno = 0,
    Ammo_Supply_Dyno = 0,
    Construction_MG42_Dyno = 0,
    Main_Door_Dyno = 0,
    Pak_Cannon_Dyno = 0,
    Side_Gate_Dyno = 0,

    ShowMovers = true,
    Movers =
    {
        "MOVER_ammogate",
    },

    /**
     * Goals to be enabled for Axis when Ammo_Storage_Gate_Destroyed is triggered.
     * If rebuilt, ATTACK goals are disabled and all DEFEND goals are enabled.
     * If the Ammo Supply is destroyed, all these goals are disabled.
     */
    AxisAmmoSupplyAreaGoalTable = table(
        "ATTACK_Charlie1",
        "ATTACK_Charlie2",
        "ATTACK_Charlie3",
        "ATTACK_Charlie5",
        "DEFEND_Charlie2",
        "DEFEND_Charlie3",
        "DEFEND_Charlie4",
        "DEFEND_Charlie5"
    ),

    /**
     * Axis goals outside Ammo Supply area when the Main Door is destroyed.
     */
    AxisSecondPartGoalTable = table(
        "DEFEND_Bravo.*",
        "PLANT_Allies_Command_Post",
        //
        "ARTILLERY_S_AxisArty.*",
        "CALLARTILLERY_AxisArty.*",
        //
        "MOBILEMG42_AxisMobileMG.*",
        //
        "MOBILEMORTAR_AxisMortar.*",
        //
        "BUILD_Construction_MG42",
        "MOUNTMG42_Construction_track",
        "REPAIRMG42_construction_track",
        //
        "MOUNTMG42_AxisMainBunkerMG",
        "REPAIRMG42_AxisMainBunkerMG"
    ),

    /**
     * Manages camping spots in the Ammo Supply area for Allies.
     * @param enable Either enable of disable the camp spots.
     */
    Allies_AmmoSupplyCamp_Management = function(enable)
    {
        goalTable = table(
            "ATTACK_Charlie.*",
            "DEFEND_Charlie2",
            "DEFEND_Charlie3",
            "DEFEND_Charlie4",
            "DEFEND_Charlie5"
        );

        SetAvailableMapGoals( TEAM.ALLIES, enable, goalTable );

        foreach( g in goalTable )
        {
            if( enable )
            {
                SetGoalPriority( g, 0.6, TEAM.ALLIES );
            }
        }

        // One covert-op for PLANT_Ammo_Storage_Gate
        // Assuming no server has a 1o1 bot config running this map...
        if( Server.MinClassCount[TEAM.ALLIES][CLASS.COVERTOPS] < 1 )
        {
            Server.MinClassCount[TEAM.ALLIES][CLASS.COVERTOPS] = 1;
        }
    },

    Allies_Command_Post_Built = function( trigger )
    {
        Map.IsAlliedCPBuilt = true;

        // Don't move until the Main Gate is destroyed
        // And ofc if the Ammo Supply is still available
        if( Map.IsMainDoorDestroyed && !Map.IsAmmoSupplyDestroyed )
        {
            Util.ChangeSpawn( TEAM.ALLIES, 5 );
        }

        Util.MapDebugPrint( "Allies_Command_Post_Built" );
    },

    Ammo_Storage_Gate_Built = function( trigger )
    {
        Map.IsAmmoStorageGateBuilt = true;

        if( !Map.IsAmmoSupplyDestroyed )
        {
            // See declaration of Map.AxisAmmoSupplyAreaGoalTable
            SetAvailableMapGoals( TEAM.AXIS, true, Map.AxisSecondPartGoalTable );
            SetAvailableMapGoals( TEAM.AXIS, false, "ATTACK_.*" );

            SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Ammo_Supply" );
        }

        Util.MapDebugPrint( "Ammo_Storage_Gate_Built" );
    },

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

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

    Allies_Command_Post_Planted = function( trigger )
    {
        Map.Allies_Command_Post_Dyno += 1;
        // SetAvailableMapGoals( TEAM.AXIS, false, "PLANT_Allies_Command_Post" );

        Util.MapDebugPrint( "Allies_Command_Post_Planted" );
    },

    Ammo_Storage_Gate_Planted = function( trigger )
    {
        Map.Ammo_Storage_Gate_Dyno += 1;
        // SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Ammo_Storage_Gate" );

        Util.MapDebugPrint( "Ammo_Storage_Gate_Planted" );
    },

    Ammo_Supply_Planted = function( trigger )
    {
        Map.Ammo_Supply_Dyno += 1;
        // SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Ammo_Supply" );

        Util.MapDebugPrint( "Ammo_Supply_Planted" );
    },

    // Construction_MG42_Planted = function( trigger )
    // {
        // Map.Construction_MG42_Dyno += 1;
        // // SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Construction_MG42" );

        // Util.MapDebugPrint( "Construction_MG42_Planted" );
    // },

    Main_Door_Planted = function( trigger )
    {
        Map.Main_Door_Dyno += 1;
        // SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Main_Door" );

        Util.MapDebugPrint( "Main_Door_Planted" );
    },

    Pak_Cannon_Planted = function( trigger )
    {
        Map.Pak_Cannon_Dyno += 1;
        // SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Pak_Cannon" );

        Util.MapDebugPrint( "Pak_Cannon_Planted" );
    },

    Side_Gate_Planted = function( trigger )
    {
        Map.Side_Gate_Dyno += 1;
        // SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Side_Gate" );

        Util.MapDebugPrint( "Side_Gate_Planted" );
    },

    Allies_Command_Post_Defused = function( trigger )
    {
        Map.Allies_Command_Post_Dyno -= 1;
        if ( Map.Allies_Command_Post_Dyno < 1 )
            { SetAvailableMapGoals( TEAM.AXIS, true, "PLANT_Allies_Command_Post" ); }

        Util.MapDebugPrint( "Allies_Command_Post_Defused" );
    },

    Ammo_Storage_Gate_Defused = function( trigger )
    {
        Map.Ammo_Storage_Gate_Dyno -= 1;
        if ( Map.Ammo_Storage_Gate_Dyno < 1 )
            { SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Ammo_Storage_Gate" ); }

        Util.MapDebugPrint( "Ammo_Storage_Gate_Defused" );
    },

    Ammo_Supply_Defused = function( trigger )
    {
        Map.Ammo_Supply_Dyno -= 1;
        if ( Map.Ammo_Supply_Dyno < 1 )
            { SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Ammo_Supply" ); }

        Util.MapDebugPrint( "Ammo_Supply_Defused" );
    },

    // Construction_MG42_Defused = function( trigger )
    // {
        // Map.Construction_MG42_Dyno -= 1;
        // if ( Map.Construction_MG42_Dyno < 1 )
            // { SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Construction_MG42" ); }

        // Util.MapDebugPrint( "Construction_MG42_Defused" );
    // },

    Main_Door_Defused = function( trigger )
    {
        Map.Main_Door_Dyno -= 1;
        if ( Map.Main_Door_Dyno < 1 )
            { SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Main_Door" ); }

        Util.MapDebugPrint( "Main_Door_Defused" );
    },

    Pak_Cannon_Defused = function( trigger )
    {
        Map.Pak_Cannon_Dyno -= 1;
        if ( Map.Pak_Cannon_Dyno < 1 )
            { SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Pak_Cannon" ); }

        Util.MapDebugPrint( "Pak_Cannon_Defused" );
    },

    Side_Gate_Defused = function( trigger )
    {
        Map.Side_Gate_Dyno -= 1;
        if ( Map.Side_Gate_Dyno < 1 )
            { SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Side_Gate" ); }

        Util.MapDebugPrint( "Side_Gate_Defused" );
    },

    Allies_Command_Post_Destroyed = function( trigger )
    {
        Map.IsAlliedCPBuilt = false;

        Util.MapDebugPrint( "Allies_Command_Post_Destroyed" );
    },

    Ammo_Storage_Gate_Destroyed = function( trigger )
    {
        Map.IsAmmoStorageGateBuilt = false;

        if ( Map.IsAmmoSupplyDestroyed )
        {
            SetAvailableMapGoals( TEAM.AXIS, false, "BUILD_Ammo_Storage_Gate" );
        }
        else
        {
            if ( Map.IsMainDoorDestroyed )
            {
                SetAvailableMapGoals( TEAM.AXIS, false, {
                    "DEFEND_.*",
                    "MOUNTMG42_.*",
                    "PLANT_Allies_Command_Post",
                    "REPAIRMG42_.*"
                });
                SetAvailableMapGoals( TEAM.AXIS, true, Map.AxisAmmoSupplyAreaGoalTable );

                SetAvailableMapGoals( TEAM.ALLIES, true, "PLANT_Ammo_Supply" );
            }
        }

        Util.MapDebugPrint( "Ammo_Storage_Gate_Destroyed" );
    },

    Ammo_Supply_Destroyed = function( trigger )
    {
        Map.IsAmmoSupplyDestroyed = true;

        // Back to the Forward Bunker
        Util.ChangeSpawn( TEAM.ALLIES, 3 );

        SetAvailableMapGoals( TEAM.AXIS, true, Map.AxisSecondPartGoalTable );
        SetAvailableMapGoals( TEAM.AXIS, false, {
            "ATTACK_.*",
            "BUILD_Ammo_Storage_Gate",
            "DEFEND_Charlie.*",
            "PLANT_Allies_Command_Post",
            "PLANTMINE_AmmoStorageGate.*",
        });

        SetAvailableMapGoals( TEAM.ALLIES, false, "BUILD_Allies_Command_Post" );

        Map.Allies_AmmoSupplyCamp_Management( false );

        Util.MapDebugPrint( "Ammo_Supply_Destroyed" );
    },

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

    Main_Door_Destroyed = function( trigger )
    {
        Map.IsMainDoorDestroyed = true;

        // blockwall flags actualization
        sleep(2);

        // Goals which depend on objectives status
        if ( !Map.IsAmmoSupplyDestroyed )
        {
            // If the Allied CP is built, move the spawn
            if( Map.IsAlliedCPBuilt )
            {
                Util.ChangeSpawn( TEAM.ALLIES, 5 );
            }

            SetAvailableMapGoals( TEAM.AXIS, true, {
                "BUILD_Ammo_Storage_Gate",
                "PLANTMINE_AmmoStorageGate.*",
            });

            SetAvailableMapGoals( TEAM.ALLIES, true, {
                "ATTACK_Charlie.*",
                "PLANT_Ammo_Supply",
                "PLANT_Ammo_Storage_Gate",
            });

            Map.Allies_AmmoSupplyCamp_Management( true );

            if( !Map.IsAmmoStorageGateBuilt )
            {
                SetAvailableMapGoals( TEAM.AXIS, true, Map.AxisAmmoSupplyAreaGoalTable );
            }
        }

        if (Map.IsAmmoStorageGateBuilt || Map.IsAmmoSupplyDestroyed)
        {
            SetAvailableMapGoals( TEAM.AXIS, true, Map.AxisSecondPartGoalTable );
        }

        SetAvailableMapGoals( TEAM.AXIS, true, {
            "BUILD_Pak_Cannon",
            "PLANTMINE_MainBunkerEntrance.*",
        });
        SetAvailableMapGoals( TEAM.AXIS, false, {
            "DEFEND_Alpha.*",
            "MOBILEMG42_Alpha.*",
            "MOUNTMG42_ForwardBunkerMG",
            "PLANTMINE_Alpha.*",
            "REPAIRMG42_ForwardBunkerMG",
        });

        SetAvailableMapGoals( TEAM.ALLIES, true, {
            "ATTACK_Bravo.*",
            "BUILD_Allies_Command_Post",
            // "PLANT_Construction_MG42",
            "PLANT_Pak_Cannon",
        });
        SetAvailableMapGoals( TEAM.ALLIES, false, {
            "ATTACK_AlliesStart.*",
            "ATTACK_FlagCaptured.*",
        });

        Util.MapDebugPrint( "Main_Door_Destroyed" );
    },

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

    Side_Gate_Destroyed = function( trigger )
    {
        SetAvailableMapGoals( TEAM.AXIS, true, {
            "BUILD_Ammo_Storage_Gate",
            "BUILD_Pak_Cannon",
        });

        SetAvailableMapGoals( TEAM.ALLIES, true, {
            "BUILD_Allies_Command_Post",
        });

        // Remains available for some reason, but bots don't care about it
        SetAvailableMapGoals( TEAM.ALLIES, false, "PLANT_Side_Gate" );

        Util.MapDebugPrint( "Side_Gate_Destroyed" );
    },

    forwardbunker_flag_Axis_Captured = function( trigger )
    {
        SetAvailableMapGoals( TEAM.AXIS, true, {
            "MOUNTMG42_ForwardBunkerMG",
            "REPAIRMG42_ForwardBunkerMG",
        });

        SetAvailableMapGoals( TEAM.ALLIES, true, {
            "ATTACK_AlliesStart.*",
            "CHECKPOINT_forwardbunker_flag",
        });

        Util.MapDebugPrint( "forwardbunker_flag_Axis_Captured" );
    },

    forwardbunker_flag_Allies_Captured = function( trigger )
    {
        SetAvailableMapGoals( TEAM.AXIS, true, "CHECKPOINT_forwardbunker_flag" );
        SetAvailableMapGoals( TEAM.AXIS, false, {
            "MOUNTMG42_ForwardBunkerMG",
            "REPAIRMG42_ForwardBunkerMG",
        });

        SetAvailableMapGoals( TEAM.ALLIES, true, "ATTACK_FlagCaptured.*" );
        SetAvailableMapGoals( TEAM.ALLIES, false, "ATTACK_AlliesStart.*" );

        Util.MapDebugPrint( "forwardbunker_flag_Allies_Captured" );
    },
};

global OnMapLoad = function()
{
    // *** TRIGGERS ***
    OnTrigger( "Allied Command Post constructed. Charge speed increased!", Map.Allies_Command_Post_Built );
    OnTrigger( "Axis team has built the Ammo Storage Gate!", Map.Ammo_Storage_Gate_Built );
    OnTrigger( "Axis team has built the mg42!", Map.Construction_MG42_Built );
    OnTrigger( "Axis team have repaired the Pak gun!", Map.Pak_Cannon_Built );
    OnTrigger( "Planted at the Allies Command Post.", Map.Allies_Command_Post_Planted );
    OnTrigger( "Planted at the Ammo Storage Gate.", Map.Ammo_Storage_Gate_Planted );
    OnTrigger( "Planted at The Ammo Supply.", Map.Ammo_Supply_Planted );
    // OnTrigger( "Planted at the Construction MG42.", Map.Construction_MG42_Planted );
    OnTrigger( "Planted at the Main Door.", Map.Main_Door_Planted );
    OnTrigger( "Planted at The Pak Cannon.", Map.Pak_Cannon_Planted );
    OnTrigger( "Planted at the Side Gate.", Map.Side_Gate_Planted );
    OnTrigger( "Defused at the Allies Command Post.", Map.Allies_Command_Post_Defused );
    OnTrigger( "Defused at the Ammo Storage Gate.", Map.Ammo_Storage_Gate_Defused );
    OnTrigger( "Defused at The Ammo Supply.", Map.Ammo_Supply_Defused );
    // OnTrigger( "Defused at the Construction MG42.", Map.Construction_MG42_Defused );
    OnTrigger( "Defused at the Main Door.", Map.Main_Door_Defused );
    OnTrigger( "Defused at The Pak Cannon.", Map.Pak_Cannon_Defused );
    OnTrigger( "Defused at the Side Gate.", Map.Side_Gate_Defused );
    OnTrigger( "Axis team has destroyed the Allies Command Post!", Map.Allies_Command_Post_Destroyed );
    OnTrigger( "Allied team has destroyed the Ammo Storage Gate!", Map.Ammo_Storage_Gate_Destroyed );
    OnTrigger( "Allies have destoyed Ammo Supply!", Map.Ammo_Supply_Destroyed );
    // OnTrigger( "Allied team has destroyed the mg42!", Map.Construction_MG42_Destroyed );
    OnTrigger( "Allied team has breached the Main Door and secured the Forward Shack!", Map.Main_Door_Destroyed );
    OnTrigger( "Allied team have damaged the Pak gun!", Map.Pak_Cannon_Destroyed );
    OnTrigger( "Allies have breached the Side Gate!", Map.Side_Gate_Destroyed );
    OnTrigger( "Axis capture the forward Shack!", Map.forwardbunker_flag_Axis_Captured );
    OnTrigger( "Allies captured the Forward Bunker!", Map.forwardbunker_flag_Allies_Captured );

    // *** CLEAR ALL GOALS FOR BOTH TEAMS ***
    Util.DisableGoal( ".*", true ); // All but Routes

    // *** AXIS GOALS ***
    SetAvailableMapGoals( TEAM.AXIS, true, {
        // "BUILD_Ammo_Storage_Gate",
        // "BUILD_Pak_Cannon",
        "DEFEND_Alpha.*",
        "MOBILEMG42_Alpha.*",
        "MOUNTMG42_ForwardBunkerMG",
        "PLANTMINE_Alpha.*",
        "REPAIRMG42_ForwardBunkerMG",
    });

    // *** ALLIED GOALS ***
    SetAvailableMapGoals( TEAM.ALLIES, true, {
        "ATTACK_AlliesStart.*",
        "CHECKPOINT_forwardbunker_flag",
        "PLANT_Main_Door",
        "PLANT_Side_Gate",
    });

    // *** GOALS PROPERTIES ***
    Util.SetMaxUsers( 1, "ATTACK_.*" );
    Util.SetMaxUsers( 1, "BUILD_Allies_Command_Post" );
    Util.SetMaxUsers( 1, "DEFEND_.*" );
    Util.SetMaxUsers( 1, "MOUNTMG42_.*" );
    Util.SetMaxUsers( 1, "PLANT_Allies_Command_Post" );
    Util.SetMaxUsers( 3, "CHECKPOINT_.*" );

    Util.SetGoalOffset( 280, 20, -80, "PLANT_Ammo_Storage_Gate" );
    Util.SetGoalOffset( 0, -75, -40,  "PLANT_Ammo_Supply" );
    Util.SetGoalOffset( 50, 20, -30,  "PLANT_Side_Gate" );

    Util.AddUsePoint( "BUILD_Ammo_Storage_Gate",    Vec3( -2074, -4296, 264 ) );
    Util.AddUsePoint( "BUILD_Pak_Cannon",           Vec3( -1862, -1062, 625 ) );

    Util.ExcludeClass( "MOUNTMG42_.*", TEAM.AXIS, CLASS.MEDIC, CLASS.ENGINEER );

    SetMapGoalProperties( "ATTACK_.*", { mincamptime = 60, maxcamptime = 120 } );
    SetMapGoalProperties( "DEFEND_.*", { mincamptime = 60, maxcamptime = 120 } );

    // Managing goal priorities for Allies
    // BUILD default: 0.90
    // PLANT default: 0.81
    // Going down from 0.90 to avoid conflicting with goals like PLANTMINE
    SetGoalPriority( "PLANT_Main_Door", 0.90 );
    SetGoalPriority( "PLANT_Side_Gate", 0.90 );
    SetGoalPriority( "BUILD_Allies_Command_Post", 0.89 );
    SetGoalPriority( "PLANT_Ammo_Storage_Gate", 0.88 );
    SetGoalPriority( "PLANT_Ammo_Storage_Gate", 0.0, TEAM.ALLIES, CLASS.ENGINEER );
    SetGoalPriority( "PLANT_Ammo_Supply", 0.88 );
    SetGoalPriority( "PLANT_Pak_Cannon", 0.87 );
    SetGoalPriority( "PLANT_Construction_MG42", 0.86 );

    // Finally some for Axis
    SetGoalPriority( "BUILD_Pak_Cannon", 0.89 );
    SetGoalPriority( "BUILD_Construction_MG42", 0.88 );
    SetGoalPriority( "DEFEND_Alpha1", 0.51 );
    SetGoalPriority( "DEFEND_Alpha3", 0.51 );
    SetGoalPriority( "DEFEND_Alpha4", 0.51 );
    SetGoalPriority( "DEFEND_Charlie9", 0.51 );

    Util.MapDebugPrint( "Omni-bot map script for Nachteinbruch by Mateos" );
};

global OnBotJoin = function( bot )
{
    bot.MaxViewDistance = 2800;
    bot.IgnoreTarget( "MOVER_ammogate" );

    if( Map.IsMainDoorDestroyed && Map.IsAlliedCPBuilt && !Map.IsAmmoSupplyDestroyed )
    {
        Util.ChangeSpawn( TEAM.ALLIES, 5 );
    }
};

global InitializeRoutes = function()
{
    MapRoutes =
    {
        PLANT_Main_Door =
        {
            ROUTE_NorthernShack  =
            {
                ROUTE_NorthernRight1  =
                {
                    ROUTE_NorthernRight2  = {},
                },
            },
        },

        PLANT_Side_Gate =
        {
            ROUTE_NorthernShack  =
            {
                ROUTE_NorthernLeft1  =
                {
                    ROUTE_NorthernLeft2  =
                    {
                        ROUTE_NorthernLeft3  = {},
                    },
                },
            },
        },

        CHECKPOINT_forwardbunker_flag =
        {
            ROUTE_AxisMainBunker  =
            {
                ROUTE_AxisMainDoorAA  =
                {
                    ROUTE_AxisMainDoorAB  = {},
                    ROUTE_AxisMainDoorAC  = {},
                },
            },
        },
    };

    // Copy routes
    MapRoutes.DEFEND_Alpha1 = MapRoutes.CHECKPOINT_forwardbunker_flag;
    MapRoutes.DEFEND_Alpha2 = MapRoutes.CHECKPOINT_forwardbunker_flag;
    MapRoutes.DEFEND_Alpha3 = MapRoutes.CHECKPOINT_forwardbunker_flag;
    MapRoutes.DEFEND_Alpha4 = MapRoutes.CHECKPOINT_forwardbunker_flag;

    Util.Routes(MapRoutes);
};
