Destroy complete inventory except one item

I’m looking for a script that destroys the entire inventory, except for a single object.
Who can help me, please?

There are several of these kind of scripts here at NWN Scripts Archive: http://www.dmh-online.net/nwn/scripts/

Try this.

void main()
{
    // Get entering object
    object oEnter = GetEnteringObject();
 
    // Rob and strip the player
    if( GetIsPC(oEnter) && !(GetLocalInt(oEnter, "GotRobbed")) )
    {
        // Ensure that the robbing only happens once
        SetLocalInt(oEnter, "GotRobbed", TRUE);
        // Take away gold
        TakeGoldFromCreature(GetGold(oEnter), oEnter, TRUE);
        // Take away all inventory items
        object oNextItem = GetNextItemInInventory(oEnter);
        // This is the object you don't want to destroy. Insert the tag of the object you don't want to destroy.
	object oDontdestroy = GetObjectByTag("donotdestroy");
        while(oNextItem != OBJECT_INVALID)
        {
	    	if (oNextItem == oDontdestroy)
		{
		
		 oNextItem = GetNextItemInInventory(oEnter);

		}
            DestroyObject(oNextItem);
            oNextItem = GetNextItemInInventory(oEnter);
        }
        // Take away all worn equipments
        oNextItem = GetItemInSlot(INVENTORY_SLOT_ARMS, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_ARROWS, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BOLTS, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BELT, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BOOTS, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BULLETS, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_CLOAK, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_HEAD, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_LEFTRING, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
        oNextItem = GetItemInSlot(INVENTORY_SLOT_NECK, oEnter);
        if(oNextItem != OBJECT_INVALID)
            DestroyObject(oNextItem);
    }
}
1 Like

Have you checked this out? It may provide insight…
https://neverwintervault.org/project/nwn1/script/spnarts-dmwand

Baseline solution:

void main()
{
    object oItem;
    object oDontDestroy;

    // get object to save via its tag
    oDontDestroy = GetItemPossessedBy(OBJECT_SELF, "TAG_OF_THE_ITEM");

    oItem = GetFirstItemInInventory(OBJECT_SELF);

    while(GetIsObjectValid(oItem))
    {
        if(oItem != oDontDestroy)
        {
            DestroyObject(oItem);
        }
        oItem = GetNextItemInInventory(OBJECT_SELF);
    }
}

To destroy worn equipment call in addition to above:

DestroyObject(GetItemInSlot(iSlot, OBJECT_SELF))

where iSlot is one of INVENTORY_SLOT_* constant. Call it for all inventory slots except INVENTORY_SLOT_CARMOUR.

Combine NWShackers option with this destroy all script:

void main()
{
	object oPC = GetPCSpeaker();
	object oTarget = GetObjectByTag("rip_off_box");
	object oItem;
	object oFM = GetFirstFactionMember(oPC, FALSE);
	while (GetIsObjectValid(oFM))
	{	
		oItem = GetFirstItemInInventory(oFM);
		while (GetIsObjectValid(oItem))
		{
			CopyItem(oItem, oTarget);
			DestroyObject(oItem, 0.f, FALSE);
			
			oItem = GetNextItemInInventory(oFM);
		}
	}
	int nSlot = 0;
	while (nSlot <= NUM_INVENTORY_SLOTS)
	{
		oItem = GetItemInSlot(nSlot, oFM);
		if (GetIsObjectValid(oItem))
		{
			CopyItem(oItem, oTarget);
			DestroyObject(oItem, 0.f, FALSE);
			
			nSlot ++;	
		}
		oFM = GetNextFactionMember(oPC, FALSE);
	}
}

Thaks a lot guys! I will test them in a few of hours!

You don’t help somebody with a quite simple question by pasting a full-featured script and telling them to combine who knows which parts with other solution. Keep it simple. There are several issues with this code:

  • It doesn’t compile because there is no third argument to DestroyObject in NWN1.
  • GetFirstFactionMember is unneeded by OP - just go with oPC.
  • There is no information that this script moves items to object with rip_off_box tag rather than destroys them (what OP asked for).
  • CopyItem(oItem, oTarget) will eradicate all local variables on the items - always use CopyItem(oItem, oTarget, TRUE) unless you want a clean slate item.
  • while (nSlot <= NUM_INVENTORY_SLOTS) takes away the creature hide - should be while (nSlot < INVENTORY_SLOT_CARMOUR).

Well it was in the NWN2 lists.
Sorry for offering help - I wasn’t going to write everything since the actual usage will differ.
Mine was just for reference - if that is wrong then calm down a little, ok?

That’s a little harsh there NWNShacker… It’s not a competition.

1 Like

Nothing harsh there. I’m not saying I have to always be right or that @Morbane should not try, just noting that a larger script (from a different game as it turns out) may be less helpful than a bare-bones solution that works immediately in given context when copy-pasted into the toolset. It’s easier to go from simpler to complex scripts than the other way.

ok, you’re the hero @NWShacker
nothing with a broader aspect is useful since the OP is by your implication, unable to fathom my overly complex and ‘useless’ version.

Apologies if you didn’t like that reply but there is no reason to keep acting hostile.

It would’ve helped if you just stated what that script does and what are its prerequisites so whoever is going to read this thread today or in the future will have easier time understanding that some portions are unnecessary to achieve what OP asked for.

1 Like

You’re right, I agree. I did post a script with extra bagage. It was careless and I knew it was over the top. But I always found that the more variety in examples that i either found or was shown, verily always gave me a better overall understanding if NWScript. I have been away from the communities, both NWN2 and NWN1. I did then and continue to now, peruse both forums and now Discord for every bit of information I can absorb - to both catch back up and to develop new understanding as an ongoing point of progression. I simply believe that doing so is implied when someone posts in any of the NW forums or chats.

Glad to hear that.

Naturally it’s okay to experiment and the more examples are provided the more experience is gained, so to speak. While a basic solution “just works” (i.e. solves the core of the problem) something extra can be useful / stimulating as well.

I’m not trying to discourage anyone from posting code (see above). What I’m saying is that it is important to state what is being done, even briefly (unless the snippet is really small). For example: “this script moves all stuff to a container with tag TAG instead of deleting them”. Either by a label or in inline comments. This is guaranteed to be useful for somebody but may copy&pasted by someone lured by thread’s title who will wonder why nothing happens if there is no valid CopyItem receptacle.


Sorry @MillaJ for derailing the thread.

Hi again. I tested the script, but some plot items are still here…
Morover it should not work with the DMs…

My old script was:

void main()
{
    // Get the creature who triggered this event.
    object oPC = GetEnteringObject();

    // Only fire for (real) PCs.
    if ( !GetIsPC(oPC)  ||  GetIsDMPossessed(oPC) )
        return;

    // Only fire once per PC.
    if ( GetLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF)) )
        return;
    SetLocalInt(oPC, "DO_ONCE__" + GetTag(OBJECT_SELF), TRUE);
}

I haven’t tested this, but maybe this would work?

void PrepForDestruction(object oTarget)
{
    SetPlotFlag(oTarget,FALSE);
    SetImmortal(oTarget,FALSE);
    AssignCommand(oTarget,SetIsDestroyable(TRUE,FALSE,FALSE));
}

void main()
{
    // Get entering object
    object oEnter = GetEnteringObject();

    // Only fire for (real) PCs.
    if ( !GetIsPC(oEnter)  ||  GetIsDMPossessed(oEnter) )
        return;

 
    // Rob and strip the player
    if( GetIsPC(oEnter) && !(GetLocalInt(oEnter, "GotRobbed")) )
    {
        // Ensure that the robbing only happens once
        SetLocalInt(oEnter, "GotRobbed", TRUE);
        // Take away gold
        TakeGoldFromCreature(GetGold(oEnter), oEnter, TRUE);
        // Take away all inventory items
        object oNextItem = GetNextItemInInventory(oEnter);
       // This is the object you don't want to destroy. Insert the tag of the object you don't want to destroy.
	object oDontdestroy = GetObjectByTag("donotdestroy");
        while(oNextItem != OBJECT_INVALID)
        {
	    	if (oNextItem == oDontdestroy)
			{
		
		 	oNextItem = GetNextItemInInventory(oEnter);

			}
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
            oNextItem = GetNextItemInInventory(oEnter);
        }
        // Take away all worn equipments
        oNextItem = GetItemInSlot(INVENTORY_SLOT_ARMS, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_ARROWS, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BOLTS, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BELT, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BOOTS, oEnter);
        if(oNextItem != OBJECT_INVALID)
	   {
	   PrepForDestruction(oNextItem);
           DestroyObject(oNextItem);
	   }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_BULLETS, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_CARMOUR, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_CHEST, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_CLOAK, oEnter);
        if(oNextItem != OBJECT_INVALID)
	   {
	   PrepForDestruction(oNextItem);
           DestroyObject(oNextItem);
	   }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oEnter);
        if(oNextItem != OBJECT_INVALID)
	   {
	   PrepForDestruction(oNextItem);
           DestroyObject(oNextItem);
	   }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_RIGHTRING, oEnter);
        if(oNextItem != OBJECT_INVALID)
	    {
	    PrepForDestruction(oNextItem);
            DestroyObject(oNextItem);
	    }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_HEAD, oEnter);
        if(oNextItem != OBJECT_INVALID)
	   {
	   PrepForDestruction(oNextItem);
           DestroyObject(oNextItem);
	   }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oEnter);
        if(oNextItem != OBJECT_INVALID)
	   {
	   PrepForDestruction(oNextItem);
           DestroyObject(oNextItem);
	   }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_LEFTRING, oEnter);
        if(oNextItem != OBJECT_INVALID)
	   {
	   PrepForDestruction(oNextItem);
           DestroyObject(oNextItem);
	   }
        oNextItem = GetItemInSlot(INVENTORY_SLOT_NECK, oEnter);
        if(oNextItem != OBJECT_INVALID)
	  {
	  PrepForDestruction(oNextItem);
          DestroyObject(oNextItem);
	  }
    }
}
1 Like

I don’t think the SetImmortal(oTarget,FALSE); is needed. And all that GetItemInSlot stuff is just crying out to be done in a loop :slight_smile:

Thanks a lot andgalf

You’re welcome. Happy to help. So it worked MillaJ?

@meaglyn Yes, I know . You’re probably right about the SetImmortal. I took the whole PrepForDestruction function from the ga_destroy_item stock script, and most of the other things in that script are from a script in NWN Scripts Archive. And since I’m not that good at scripting, I didn’t go through it all to make it more neat. Maybe I could do it with my knowledge I have now, but I was lazy…:slight_smile: . kevL_s, Aqvilinus or travus, among many others, I know could do this code more compact in a heartbeat. But the important thing is if it works or not.

1 Like