Destroy specific item in inventory

I’m looking for a script that would allow me to destroy one specific item in the inventory. Preferably if it could be used via in game dm_runscript command line. The item isn’t undroppable but I want it completely removed from the module when it is already started and there are no other ways to do it; like a container that destroys everything placed in it etc.

There’s a stock script in NWN2 that is called ga_destroy. It looks like this. Not sure it would work in NWN1 but maybe?

// ga_destroy
/*
    This script destroys objects
        sTag        = The tag(s) of the object(s) to destroy. You can pass multiple
                      tags, seperated by commas (NO SPACES) to destroy multiple objects
                      (ie. "Object1,Object2,Object3")
                      NOTE: There may eventually be a function to eat white space
                      (See Mantis 3296), but for now do not put spaces in the string.
        iInstance   = The instance of the object to destroy. Pass -1 to destroy
                      all instances.  Pass 0 to destroy the first instance.
        fDelay      = The delay before destroying the object(s)

*/
// TDE 3/7/05
// ChazM 3/8/05   - commented and tweaked.
// ChazM 6/7/05   - fixed bug, modified comment
// BMA-OEI 1/11/06 removed default param

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

// detroy all objects (iInstance=-1) or a specific instance of object
void Destroy(string sTagString, int iInstance = 0, float fDelay = 0.0)
{
    if (iInstance == -1)
    {   // delete all objects
        int iInst = 0;
        object oObject = GetObjectByTag(sTagString, iInst);

        while (GetIsObjectValid(oObject))
        {
			PrepForDestruction(oObject);
            DestroyObject (oObject, fDelay);
            iInst ++;
            oObject = GetObjectByTag(sTagString, iInst);
        }
    }
    else
    {   // delete a specific instance of object
		object oTarget = GetObjectByTag(sTagString,iInstance);
		if(GetIsObjectValid(oTarget))
		{
			PrepForDestruction(oTarget);
        	DestroyObject (oTarget, fDelay);
		}
    }
}



void main(string sTagString, int iInstance, float fDelay)
{
    string sNewString = sTagString;
    int iLen = GetStringLength(sTagString);
    int iCommaPos = FindSubString( sNewString, "," ); //find first comma

    while(iCommaPos != -1)
    {
        // get first tag and destroy it
        string sTempString = GetSubString(sNewString , 0, iCommaPos);
        Destroy(sTempString, iInstance, fDelay);

        // drop first tag and comma
        sNewString  = GetSubString(sNewString, iCommaPos + 1, iLen);
        // determine new length
        iLen = GetStringLength(sNewString);
        // get next comma position (returns -1 if not found)
        iCommaPos = FindSubString(sNewString, "," );
    }

    //sNewString is equal to last tag to destroy
    Destroy(sNewString, iInstance, fDelay);
}

EDIT: Just tried to open the NWN1 toolset and compiling this. Apparently you can’t have strings or ints in the void main? How odd. I thought it worked similarly to NWN2 in this regard.

Maybe try something like this instead:

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

void Destroy(string sTagString, float fDelay = 0.0)
{

		object oTarget = GetObjectByTag(sTagString);
		if(GetIsObjectValid(oTarget))
		{
			PrepForDestruction(oTarget);
        	DestroyObject (oTarget, fDelay);
		}

}


void main()
{
    string sNewString = "tagofitem";

    //sNewString is equal to last tag to destroy
    Destroy("tagofitem");
}

EDIT: Just to be clear: You need to change the “tagofitem” to the tag of the item you want destroyed.

3 Likes

Exactly what I need and it works! Thanks andgalf

1 Like

In NWN1, there is no mechanism for passing variables into a void main() routine. Instead, the main routine has to either have the variables established by a declaration or be able to find them itself, such as from a module variable.
What we’d do in NWN1 is to use the module call OnClientEnter and then search the inventory of every entering player for the object using GetFirst/NextItemInInventory which already searches by tag, then destroying every instance found.
In NWN1, there is no need to change flags before using DestroyObject(). It can be plot, immortal or whatever and the command still works. The presumption is that the script writer knows what they’re doing and if they didn’t want a plot item destroyed, they’d check the plot flag first before using the DestroyObject() command. I assume this is so that a plot item can be destroyed by a script once the item has served its purpose and would otherwise become just inventory clutter.

It may not help here, but in EE there is a mechanism, which can be invoked in two ways:

  • SetScriptParam() followed by ExecuteScript()
  • Set the parameter(s) in the ActionTaken tab of a conversation

The receiving script can use GetScriptParam().

You’re right. I had overlooked that new feature in EE.