#include "x4_inc_functions"
#include "_sh_inc_list"

void SimulateEvents(object oPC, object oArea, object oWaypoint)
{
    //Simulate the OnExit event of the area - we do not use the normal OnExit to avoid event/encounter reloading in case of a loaded save file
    SetLocalObject(GetModule(), "TravellingPC", oPC);
    ExecuteScript("execute_onexit", oArea);
    DeleteLocalObject(GetModule(), "TravellingPC");

    if (GetLocalInt(oPC, "Miles") != 0)
    {
        //Simulate the OnEnter event of the area - we do not use the normal OnEnter to avoid event/encounter reloading in case of a loaded save file
        object oRandomArea = GetArea(oWaypoint);
        SetLocalObject(GetModule(), "TravellingPC", oPC);
        ExecuteScript("execute_onenter", oRandomArea);
        DeleteLocalObject(GetModule(), "TravellingPC");
    }
}

void main()
{
    object oPC = GetPCSpeaker();
    object oArea = GetArea(OBJECT_SELF);

    //Halt if the PC is in a different area
    if (GetLocalString(oPC, "AreaString") != GetLocalString(oArea, "AreaString")) return;

    //A conditional check
    float fDistance;
    object oMember = GetFirstFactionMember(oPC);
    while (GetIsObjectValid(oMember))
    {
        fDistance = GetDistanceBetween(oMember, oPC); //Get the distance between the PC and a party member
        if (oPC != oMember && (fDistance == 0.0 || fDistance > 10.0)) //If they are in different areas or the distance is longer than 10 meters...
        {
            FloatingTextStringOnCreature("Your party wants to travel, but you are absent!", oMember, FALSE);
            return;
        }
        oMember = GetNextFactionMember(oPC);
    }

    //Get area string
    string sAreaString = GetLocalString(oArea, "AreaString");
    string sRegionString = GetStringLeft(sAreaString, 1);

    //Get the list of free areas
    string sList = "sList"+sRegionString;
    object oList = GetLocalObject(GetModule(), sList);

    //Get the number of free areas
    int nCount = ListGetElementCount(oList);

    //Randomly select a free area
    int nElementIndex = Random(nCount)+1;
    string sRandomAreaString = ListGetString(oList, nElementIndex);

    //Teleport the PC (and their party) to the northern entrance waypoint of the chosen area
    object oWaypoint = GetWaypointByTag("exit_wp_"+sRandomAreaString+"_n");
    object oExit = GetWaypointByTag("exit_wp_"+sRegionString+"_0");
    int nDistance = GetLocalInt(GetFactionLeader(oPC), "Miles");
    //Let's store the party leader on the area about to be entered
    if (nDistance != 1)
    {
        SetLocalObject(GetArea(oWaypoint), "PartyLeader", GetFactionLeader(oPC));
    }
    //Now let's move everyone
    object oParty = GetFirstFactionMember(oPC, FALSE);
    while ( GetIsObjectValid(oParty) )
    {
        SetLocalInt(oParty, "Miles", nDistance); //Set everyone's distance travelled to that of the party leader
        SetLocalInt(oParty, "CanDiscover", 0); //The last area transition was towards the exit, so a player can't run into any new villages/dungeons/chests
        AssignCommand(oParty, ClearAllActions());

        SetLocalInt(oParty, "Miles", GetLocalInt(oParty, "Miles")-1);
        if (GetLocalString(GetModule(), "MODE") == "LOCAL" && GetIsPC(oParty)) SetCampaignInt(CharacterDB(oParty), "MILES", GetLocalInt(oParty, "Miles")); //store miles travelled in LOCAL mode
        if (GetLocalInt(oParty, "Miles") == 0) DelayCommand(0.1, AssignCommand(oParty, JumpToObject(oExit)));
        else DelayCommand(0.1, AssignCommand(oParty, JumpToObject(oWaypoint)));

        oParty = GetNextFactionMember(oPC, FALSE);
    }

    //DelayCommand(0.1, SimulateEvents(oPC, oArea, oWaypoint));
}