Jump to content

looking for a more knowledge scripters eyes


Sumomo Cheri
 Share

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

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

Recommended Posts

So trying to improve on a working script ive tossed together poorly , So far it Takes name of object and counts the contents and adds it as a Float text an keeps updating on any changes and touches happy with this part , it also allows public drag and drop . but the problem im running into is compiling the list feature so that instead of it showing a new line of chat for each item that same items are placed on a single line with x amount.  so far have attempted to get rid of the numbers at the end of same items so that i can then have it see them all as same item and give the amount but im hitting a dead end and could use some fresh eyes here. 

string num_kill(string item_name)
{
    integer all_clear;
    list numbers = ["1","2","3","4","5","6","7","8","9","0"];
    do{
        string end_number = llGetSubString(item_name,-1,-1);
        if(llListFindList(numbers,[end_number])!=-1){item_name = llStringTrim(llDeleteSubString(item_name,-1,-1),STRING_TRIM);}
        else {all_clear = !all_clear;}
    }while(!all_clear);
    return item_name;
}
setTitle()

{
    integer items = llGetInventoryNumber(INVENTORY_OBJECT);
    llSetText(llGetObjectName() + "\n" + (string)items + " Items", <0.004, 1.0, 0.043>, 1.0);
}
list inventory_items;
default
{
    state_entry()
    {
       llAllowInventoryDrop(TRUE);
   setTitle();
           integer counter; 
        integer item_count = llGetInventoryNumber(INVENTORY_OBJECT);

        for(counter = 0; counter < item_count; counter++)
     
        {
            inventory_items += [llGetInventoryName(INVENTORY_OBJECT,counter)];
          
                }
    }
               
    changed(integer change)
    {
        if ( change & (CHANGED_ALLOWED_DROP | CHANGED_INVENTORY ))
        {
            setTitle();
             inventory_items = []; 
            
            integer counter; 
            integer item_count = llGetInventoryNumber(INVENTORY_OBJECT);
           
           
            for(counter = 0; counter < item_count; counter++)
         
              {
               
                inventory_items += [llGetInventoryName(INVENTORY_OBJECT,counter)];
                setTitle();
            }
        }
    }
        touch_end(integer n )
    {
        {
        integer i;
        for( i = 0; i < n; i++ )
        {
            if (llDetectedKey(i) != llGetOwner()) //anyone
            {
                setTitle();
            }
            else if (llDetectedKey(i) == llGetOwner()) //owner
            {
               llOwnerSay("\n"+llDumpList2String(inventory_items,"\n"));    
        setTitle();      
            }
        }
    }
}    
}     

Example of the list feature of what its doing vs. what im aiming for.

Object: 

apple

apple 

apple

banana             

// What i would like it to do 

Object: 

apple x 3

banana x1

Link to comment
Share on other sites

I think what I'd do is make the inventory_items list strided, with a name followed by a counter for each item. When examining items from the inventory, I'd look to see if it's already in the list and if it is just increment the counter, and if it isn't add it and a counter set to 1 to the list.

            for (counter = 0; counter < item_count; counter++)
            {
                string name = llGetInventoryName(INVENTORY_OBJECT,counter);
                integer index = llListFindList (inventory_items, [name]);
                if (index > -1) inventory_items = llListReplaceList (inventory_items, llList2Integer (inventory_items, index + 1) + 1, index + 1, index + 1);
                else inventory_items += [name, 1];
                setTitle();
            }

This does, of course make the output code more involved:

            else if (llDetectedKey(i) == llGetOwner()) //owner
            {
                string text;
                integer length = llGetListLength (inventory_items);
                integer index = 0;
                while (index < length)
                {
                    text += "\n" + llList2String (inventory_items, index) + " x " + llList2String (inventory_items, index + 1);
                    index += 2;
                }
                llOwnerSay(text);    
                setTitle();      
            }

The other way might be to keep parallel lists, one with the name of the items and the other with their counters. This way the item name and it's counter would each have the same index in their own lists. But the strided list thought came to me first, so that's what I'm sticking with.

Edited by KT Kingsley
Rename a variable I called counter in the second code example to index, to avoid confusion with the item counters
Link to comment
Share on other sites

I wrote this off the top of my head but I can't get in-world right now to see if it even compiles. It's pretty straightforward logic, though.

default
{
    state_entry()
    {
        list inventory = ["apple", "pear", "apple", "orange", "apple", "pear"];
        list counts = [];
        integer i = 0;

        while (i < llGetListLength(inventory))
        {   // For every item, see if this item is already accounted for.
            // "apple" or "Apple" or "APPLE" --> "apple x"
            string item = llToLower(llList2String(inventory, i++)) + " x";
            integer index = llListFindList(counts, (list)item));
            if (index == -1)
            {   // Not already in the list, add a new one.
                counts += item;
                counts += 1;
            }
            else
            {   // Increase the previous amount by one.
                integer amount = 1 + llList2Integer(counts, index+1);
                counts = llListReplaceList(counts, amount, index+1, index+1);
            }
        }

        // This SHOULD create a list in this format (in order of appearance):
        // ["apple x", 3, "pear x", 2, "orange x", 1]

        i = 0;
        string output = "";
        while (i < llGetListLength(counts))
        {
            output += llList2String(counts, i++);
            output += llList2Integer(counts, i++);
            if (i < llGetListLength(counts))
                output += ", ";
        }

        // This SHOULD create a string in this format:
        // "apple x3, pear x2, orange x1"

        llOwnerSay(output);
    }
}

 

Edited by Wulfie Reanimator
Link to comment
Share on other sites

not quite what i was looking for as we are trying to have it read contents with out adding any thing to script for any items put the contents of the box when clicked by owner it should say in local chat to them a List in a descending format and not   " Item, item , item " or "item x, item '' Here is what it does currently"  Example " But for it to Drop any of the same items as 1 line of text with amount at the end

[08:05:43] (Unnamed): 
Bubble X 2
DFS !AFK GEAR X 3
Diavolo Coffee (add) X 1
honey comb bubble X 1
Total Items Packed: 7

Edited by Sumomo Cheri
Link to comment
Share on other sites

10 minutes ago, Sumomo Cheri said:

we are trying to have it read contents with out adding any thing to script for any items put the contents of the box

It was a kind of an extension of the code you already had.

You said you had managed to create remove the numbers from the ends of duplicate inventory items. So if you have those stored in one list, you can just keep going and convert that list to a "grouped list." Then, if you want to print the amounts one by one into chat, you can just ignore the part in my code that builds a single string. It's up to you to make whatever specific modifications you need.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

EDIT: Ignore this. I think the string trim inside the loop already does what I was suggesting here , which seems the most likely desired outcome.

Quote

Do you know how you want to handle inventory items named "ItemName 1 1" -- or do you have tight enough control over what gets into inventory to be sure that will never happen? (That llAllowInventoryDrop() suggests anything at all will eventually get into the object.)

This occurs if an "ItemName 1" is added into an object that already contains an "ItemName 1". (The new name won't be "ItemName 2" as it would if it were just another "ItemName" being added to an object already containing both "ItemName" and "ItemName 1".)

I guess this is a long-winded way of suggesting you really want to parse the name as a string then discard any number of numeric tokens starting from the end, assuming all the ItemName variants are equivalent.

Edited by Qie Niangao
Another look at the code
Link to comment
Share on other sites

Sumomo, with the deduping of names then num_kill() could be done a little bit more efficiently. Example:

string num_kill (string item_name)
{
   list src = llParseString2List(item_name, [" "], []); 
   if (llList2Integer(src, -1, -1)) // is a number on the end so strip it
      item_name = llDumpList2String(llDeleteSubList(src, -1, -1), " ");
   return item_name;
}

for the items I would go with a strided list of 2 elements: [name, count] as KT mentioned above. The reason is so that the list can be sorted easily for display purposes

// make a display string
items = llListSort(items, 2, TRUE);
string text;
integer n = llGetListLength(items);
integer i;
for (i = 0; i < n) i += 2)
{
   text += llList2String(items, i) + " x " + llList2String(items, i + 1) + "\n";
}
llSetText(text, <1.0, 1.0, 1.0>, 1.0);

 

 

 

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1604 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...