#include "_sh_inc_list"
#include "69_hench_lib"
#include "quest_inc"

void Body(object oExiting)
{
    //A workaround to prevent the OnEnter event body from firing after loading a saved game
    if (GetLocalInt(GetModule(), "LoadCooldown") == TRUE) return;

    if (!GetIsPC(oExiting)) return;

    WriteTimestampedLogEntry("DonExit fired"); //TEST

    //Subtrack from the counter of PCs in the area
    SetLocalInt(OBJECT_SELF, "Players", GetLocalInt(OBJECT_SELF, "Players")-1);

    //Get the connected interior area
    object oInArea = GetArea(GetWaypointByTag(GetLocalString(OBJECT_SELF, "DungeonWP")));

    //Clear the exiting player's map
    ExploreAreaForPlayer(OBJECT_SELF, oExiting, FALSE);
    ExploreAreaForPlayer(oInArea, oExiting, FALSE);
    string sAreaString = GetLocalString(OBJECT_SELF, "AreaString");
    int nPopulated = FALSE;
    object oObject;
    object oItem;

    if (GetLocalInt(OBJECT_SELF, "Players") > 0) nPopulated = TRUE;

    if (nPopulated == FALSE)
    {
        DeleteLocalInt(OBJECT_SELF, "DoorClosed");
        DeleteLocalInt(OBJECT_SELF, "IsPopulated");
        DeleteLocalInt(OBJECT_SELF, "NO_ESCAPE");
        DeleteLocalInt(OBJECT_SELF, "ThugNoticed");
        DeleteLocalInt(OBJECT_SELF, "TributePaid");
        DeleteLocalInt(OBJECT_SELF, "Level");
        DeleteLocalInt(OBJECT_SELF, "AmbushPrepared");
        DeleteLocalInt(OBJECT_SELF, "Duel");
        DeleteLocalInt(OBJECT_SELF, "MerchantTrouble");
        DeleteLocalInt(OBJECT_SELF, "DiscoveredVillage");
        DeleteLocalInt(OBJECT_SELF, "DiscoveredDungeon");
        DeleteLocalInt(OBJECT_SELF, "DungeonWP");
        DeleteLocalInt(oInArea, "DungeonWP");
        DeleteLocalObject(OBJECT_SELF, "PartyLeader");
        if (GetLocalInt(OBJECT_SELF, "Battle") != 0) MusicBattleChange(OBJECT_SELF, GetLocalInt(OBJECT_SELF, "Battle"));

        //Delete all chests, items and creatures in both areas
        oObject = GetFirstObjectInArea(OBJECT_SELF);
        while (GetIsObjectValid(oObject))
        {
            if (GetObjectType(oObject) == OBJECT_TYPE_DOOR) //let's close all doors instead of destroying them
            {
                AssignCommand(oObject, ActionCloseDoor(oObject));
            }
            if (GetObjectType(oObject) == OBJECT_TYPE_CREATURE || GetObjectType(oObject) == OBJECT_TYPE_ITEM)
            {
                if ( !GetIsPC(oObject) && !GetIsPC(GetMaster(oObject)) && !GetIsPC(GetMaster(GetMaster(oObject))) && !GetIsPC(GetLastMaster(oObject)) ) //do NOT delete PCs and their associates
                DestroyObject(oObject);
                if ( !GetIsPC(oObject) && GetIsDead(oObject) && GetLocalInt(oObject, "Escorted") == TRUE) //...unless they are a dead escorted NPC
                DestroyObject(oObject);
            }
            /*if (GetObjectType(oObject) == OBJECT_TYPE_TRIGGER)
            {
                DestroyObject(oObject);
            }*/
            if (GetTag(oObject) == "anc_tchest" || GetTag(oObject) == "anc_pcloot")
            {
                oItem = GetFirstItemInInventory(oObject);
                while (GetIsObjectValid(oItem))
                {
                    DestroyObject(oItem);
                    oItem = GetNextItemInInventory(oObject);
                }
                DestroyObject(oObject);
            }
            oObject = GetNextObjectInArea(OBJECT_SELF);
        }
        oObject = GetFirstObjectInArea(oInArea);
        while (GetIsObjectValid(oObject))
        {
            if (GetTag(oObject) == "anc_tchest" || GetObjectType(oObject) == OBJECT_TYPE_CREATURE || GetObjectType(oObject) == OBJECT_TYPE_ITEM)
            {
                if ( !GetIsPC(oObject) && !GetIsPC(GetMaster(oObject)) && !GetIsPC(GetMaster(GetMaster(oObject))) && !GetIsPC(GetLastMaster(oObject)) ) //do NOT delete PCs and their associates
                DestroyObject(oObject);
                if ( !GetIsPC(oObject) && GetIsDead(oObject) && GetLocalInt(oObject, "Escorted") == TRUE) //...unless they are a dead escorted NPC
                DestroyObject(oObject);
            }
            if (GetObjectType(oObject) == OBJECT_TYPE_TRIGGER)
            {
                DestroyObject(oObject);
            }
            if (GetTag(oObject) == "anc_lich_phylact")
            {
                DestroyObject(oObject);
            }
            if (GetTag(oObject) == "anc_pcloot")
            {
                object oItem = GetFirstItemInInventory(oObject);
                while (GetIsObjectValid(oItem))
                {
                    DestroyObject(oItem);
                    oItem = GetNextItemInInventory(oObject);
                }
                DestroyObject(oObject);
            }
            oObject = GetNextObjectInArea(oInArea);
        }

        //Add both areas to the list of free areas
        string sRegionString = GetStringLeft(sAreaString, 1);
        string sList = "sList"+sRegionString+"d";
        object oList = GetLocalObject(GetModule(), sList);
        int i;
        string sListString = ListGetString(oList, i);
        for (i = 1; i <= ListGetElementCount(oList); i++)
        {
            if (ListGetString(oList, i) == sAreaString)
            {
                i = -1;
                break;
            }
        }
        if (i != -1) ListAddString(oList, sAreaString);

        sAreaString = GetLocalString(oInArea, "AreaString");
        sList = "sListDung";
        oList = GetLocalObject(GetModule(), sList);
        sListString = ListGetString(oList, i);
        for (i = 1; i <= ListGetElementCount(oList); i++)
        {
            if (ListGetString(oList, i) == sAreaString)
            {
                i = -1;
                break;
            }
        }
        if (i != -1) ListAddString(oList, sAreaString);

        //TEST
        /*int i;
        for (i = 1; i <= ListGetElementCount(oList); i++)
        {
            FloatingTextStringOnCreature(ListGetString(oList, i), oExiting);
        }
        FloatingTextStringOnCreature("Onexit done, Onenter now", oExiting);*/
    }
}

void main()
{
    object oExiting = GetExitingObject();

    //Don't fire if oExiting is moving between the exterior and the interior area
    if (GetLocalInt(oExiting, "InTransition") == TRUE) return;
    DelayCommand(1.0, Body(oExiting));
}