Jump to content

Help: Give and Remove Inventory Script


Christopher Organiser
 Share

You are about to reply to a thread that has been inactive for 4560 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

This script works with 1 item in the Contents.  When you put 2 or more items in the Contents, it WILL give the list (inventory) to the clicker, but it will NOT remove it, and I get the following script error: Missing inventory item 'New ScriptNew Script 1' (I used 2 New Scripts as an example).  I am thinking it has something to do with parsing the list, and having the llRemoveInventory comprehend that.  I don't know how to code it, though.

list inventory; 
giveContents()
{ 
    integer num = llGetInventoryNumber(INVENTORY_ALL);
    string script = llGetScriptName();
    integer i = 0;
    inventory = [""];
    for(; i < num; ++i)
    {
        string name = llGetInventoryName(INVENTORY_ALL, i);
        if(name != script)
        {
            if(llGetInventoryPermMask(name, MASK_OWNER) & PERM_COPY)
            {
                inventory += name;
            }
        }
    }
    if(llGetListLength(inventory) > 1)
    {
        llGiveInventoryList(llDetectedKey(0), "Contents", inventory);
    }
}
    
default
{
    touch_start(integer n)
    {
        giveContents();
        if(llGetListLength(inventory) > 1)
        {
            llRemoveInventory((string)inventory);
            llOwnerSay("CLEARED!");
        }
        else
        {
            llOwnerSay("No items to clear!");
        }
    }
}

 Thank you in advance! :)

Link to comment
Share on other sites

You need a loop, like the one in the giveContents() function, inside your touch_start() event, inside the if statement.

 

I don't believe llRemoveInventory() can remove items from an agent's inventory, only from the prim it resides in.  And since the test in your if block only fires if the number of elements is GREATER than (not 'greater than or equal to'), it won't even try when the number of items is one or zero.

 

 Something more like:

list inventory;giveContents(){     integer num = llGetInventoryNumber(INVENTORY_ALL);    string script = llGetScriptName();    integer i = 0;    inventory = [];    for(; i < num; ++i)    {        string name = llGetInventoryName(INVENTORY_ALL, i);        if(name != script)        {            if(llGetInventoryPermMask(name, MASK_OWNER) & PERM_COPY)            {                inventory += [name];            }        }    }    if(llGetListLength(inventory) > 0)    {        llGiveInventoryList(llDetectedKey(0), "Contents", inventory);    }}    default{    touch_start(integer n)    {        giveContents();        integer i;        integer numInList = llGetListLength(inventory);        if(numInList > 0)        {            for(i=0; i < numInList; ++i)            {                llRemoveInventory((string)inventory);            }            llOwnerSay("CLEARED!");        }        else        {            llOwnerSay("No items to clear!");        }    }}

 

Initializing your list with [""] actually put an entry into it.  To clear a list, set it to [], as I showed above.  This will allow you to compare lengths easier.

 

Link to comment
Share on other sites

The script is suppose to give and clear the object's inventory of all items except the script that is operating.  It works fine with 1 item like another script, but when I place 2 scripts in (3 total including the operating script), I get the following script error:

"Missing inventory item 'New Script 1New Script 2'. Missing inventory item 'New Script 1New Script 2'."

It is thinking the name of the script is "NewScript1NewScript2".  I think something may need to be parsed, but I just cannot figure it out.

Link to comment
Share on other sites

Just by looking at it, I can say that if you tried Helium's script, you get the error message twice.

The error is on the line:

llRemoveInventory((string)inventory); // Wrong

You can do this... but only with one item. Beyond one item, the script takes the list of items, concatenate their names into a long string which it uses it as an item name that it will try to delete... as many times as the list length.

Use this line instead:

llRemoveInventory(llList2String(inventory, i)); // Better

You cannot delete a list of items directly, you must delete each item in the list, one by one.

Any way, since you delete the items after having given them, it is obvious that you do not need to keep their list in a global variable that will do nothing be eat your memory. Giving and deleting can go in the same function.

GiveAndDeleteContents(){     string script = llGetScriptName();    list items;    integer num = llGetInventoryNumber(INVENTORY_ALL);    integer i = 0;    for (; i < num; ++i)    {        string name = llGetInventoryName(INVENTORY_ALL, i);        if (name != script)        {            if (llGetInventoryPermMask(name, MASK_OWNER) & PERM_COPY)            {                items += [name];            }        }    }    num = (items != []); // Faster llGetListLength()    if (num)    {        llGiveInventoryList(llDetectedKey(0), "Contents", items);        for (i = 0; i < num; ++i)        {            llRemoveInventory(llList2String(items, i));        }        llOwnerSay((string)num + " items given and deleted.");    }    else    {        llOwnerSay("Nothing to give, nothing to delete.");    }}    default{    touch_start(integer n)    {        GiveAndDeleteContents();    }}

Never forget that scripts --and computers in general-- are docile slaves, not psychics. They will do exactly what you tell them to do, as many times as you want... But they never do what you want.

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4560 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...