Help with area cleanup script

Hi, im working on a module and I want to cleanup an arena from any NPC or treasure drops. I have a script for this but it give me the error “Too many instructions” and causes awful lot of lag when it detects even the placeables, waypoints and doors.

I dont know if this is readable but here is the script:

void main()
{
object oPC = GetExitingObject();
object oObject = GetFirstObjectInArea(oPC);

while (oObject!=OBJECT_INVALID)
{
if (GetObjectType(oObject)==OBJECT_TYPE_CREATURE || GetBaseItemType(oObject)!=BASE_ITEM_INVALID)
DestroyObject(oObject);
while (GetTag(oObject) == “BodyBag”)
{
object oItem = GetFirstItemInInventory(oObject);
while (GetIsObjectValid(oItem))
{
DestroyObject(oItem);
oItem = GetNextItemInInventory(oObject);
}
DestroyObject(oObject);
}
oObject = GetNextObjectInArea(OBJECT_SELF);
}
}

I guess the script runs forever if an object with tag “BodyBag” is detected. Perhaps the second while is meant to be an else if?

void main()
{
    object oPC = GetExitingObject();
    object oObject = GetFirstObjectInArea(oPC);

    while (oObject!=OBJECT_INVALID)
    {
      if (GetObjectType(oObject)==OBJECT_TYPE_CREATURE || GetBaseItemType(oObject)!=BASE_ITEM_INVALID)
      {
          // destroy NPCs and items
          DestroyObject(oObject);
      }
      else if (GetTag(oObject) == “BodyBag”)
      {
         // destroy bodybags and their inventory
         object oItem = GetFirstItemInInventory(oObject);
         while (GetIsObjectValid(oItem))
         {
            DestroyObject(oItem);
            oItem = GetNextItemInInventory(oObject);
         }
         DestroyObject(oObject);
      }
      oObject = GetNextObjectInArea(OBJECT_SELF);
   }
}
1 Like

Works like a charm. The endless loop stopped. :+1:

GetFirstObjectInArea(oPC) should read GetFirstObjectInArea(OBJECT_SELF).

See here for help with formatting code.

A bit more complex, but optimal cleaner (iterates only matching objects) somebody may find useful.

// By NWShacker, 30.10.2021
// Removes from oArea all objects with type matching iType or tag matching sTag

void NWSH_CleanArea(object oArea=OBJECT_SELF, int iType=OBJECT_TYPE_CREATURE, string sTag="BodyBag")
{
    object oOrigin;
    object oDelete;
    object oItem;
    int iDelete;

    // choose any object as origin for GetNearestObject()
    oOrigin = GetFirstObjectInArea(GetArea(oArea));

    // destroy all objects with type matching iType
    oDelete = GetNearestObject(iType, oOrigin, iDelete = 1);
    while(GetIsObjectValid(oDelete))
    {
        DestroyObject(oDelete);
        oDelete = GetNearestObject(iType, oOrigin, ++iDelete);
    }

    // destroy all objects with tag matching sTag (and their contents)
    oDelete = GetNearestObjectByTag(sTag, oOrigin, iDelete = 1);
    while(GetIsObjectValid(oDelete))
    {
        oItem = GetFirstItemInInventory(oDelete);
        while(GetIsObjectValid(oItem))
        {
            DestroyObject(oItem);
            oItem = GetNextItemInInventory(oDelete);
        }
        DestroyObject(oDelete);
        oDelete = GetNearestObjectByTag(sTag, oOrigin, ++iDelete);
    }

    // extra code in case oOrigin also matches any of the above criteria
    if((GetObjectType(oOrigin) & iType) > 0 || GetTag(oOrigin) == sTag)
    {
        oItem = GetFirstItemInInventory(oOrigin);
        while(GetIsObjectValid(oItem))
        {
            DestroyObject(oItem);
            oItem = GetNextItemInInventory(oOrigin);
        }
        DestroyObject(oOrigin);
    }
}

void main()
{
    // Destroy creatures and body bags:
    // NWSH_CleanArea(OBJECT_SELF, OBJECT_TYPE_CREATURE);

    // Destroy creatures, items on floor and body bags:
    // NWSH_CleanArea(OBJECT_SELF, OBJECT_TYPE_CREATURE|OBJECT_TYPE_ITEM);

    // Caveat: if sTag is "", this script will destroy items owned by PCs.
}

It makes sensible assumption that only actual body bags have tag “BodyBag”.

1 Like