Jump to content

Loading a List


kari1sl
 Share

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

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

Recommended Posts

I'm a novice and have discovered lists!But I can't seem to get the different list commands to find the lists. I have a bunch of lists at the start of my script (above "default") with either different numbers of items in each), and I'm trying to call each, via chat, into action ... but I don't know how.

 

Here's a stripped-down version with only two lists and the script. Ultimately, this should launch a animation with each word in the list but I haven't gotten to that (fun) part, so am using “llSay” to try to figure what's gone wrong.

 

The chat and permission work fine but when I try to use the list – llGetListLength, llList2String, or llList2List or llListReplaceList, etc - I end up either calling the NAME of the list or getting errors about "function call mismatches type or number of arguments”.

 

Help, please.

list first = ["antimony", "arsenic", "aluminum", "selenium", "hydrogen", "oxygen", "nitrogen", "rhenium"];
list second = ["nickel", "neodymium", "neptunium", "germanium", "iron", "americium", "ruthenium", "uranium", "Europium", "zirconium", "lutetium", "vanadium"];

default
{
    on_rez(integer start_param) {
llResetScript();
}
    state_entry()
        {
            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);
    }
    run_time_permissions(integer perm)
    {
        if(PERMISSION_TRIGGER_ANIMATION & perm)
{  
llOwnerSay(llGetScriptName() + " has PERMISSION_TRIGGER_ANIMATION perms for  "+(string)llGetPermissionsKey());   
llSetTimerEvent(2); //Cause the timer event to be triggered a maximum of once every 2 seconds. 
}
if (perm == 0)
{
    llOwnerSay(llGetScriptName() + " has NO perms for  "+ (string)llGetPermissionsKey());
}
      llListen( 0, "", llGetOwner(), "" ); 
    }
    listen(integer channel, string name, key id, string message)
    {
list input = llParseString2List(message, [" "], []); //the input is three variables, separated by spaces("song first 3")
 llSay(0, (string)input); //checks to see if its heard me by repeating what I said. It does. It works. The next three “llSay”s prove the Parsing workes. It does.
string gate = llList2String(input, 0) ; // “gate” assures that only a message starting with the “magic word” will initiate the animations.
string action =  llList2String(input, 1);  // “action” is the name of the list that contains the name of the animations. From this, also, my problem starts.
string level =  llList2String(input, 2);  // “level” is an integer will control the “action” (maybe – still in the planning stage: 
llSay(0, (string)gate); // works = repeats the magic word
llSay(0, (string)action);// works = says the name of the list;first” or “second”
llSay(0, (string)level); // works = repeats the integer
if (gate == "off") // when told "off"..
        {
          llSay (0, "bye.");
    llResetScript();
    } //OK, but trouble then starts (next)
else if (llList2String(input, 0) == "song")  //assures chat starts with 
{integer length = llGetListLength(action); // Error : Function call mismatches type or number of arguments
}
}
}

 

Link to comment
Share on other sites

We may need to know more about how you want to use these lists.  It appears (to me anyway) that you're hoping to use a runtime value (the action string) to determine which list-valued variable to reference, based on a match between that value and the name of the variable. If so, you can't do that; variable names are symbols known to the compiler and not to the script at runtime.

LSL lacks anything like pointer types or handles, and also lacks embedded lists, so the options are constrained, but if it's important to avoid a whole bunch of If-then-else statements (matching the action string with a series of constants), there are ways to structure the data to make that possible, but knowing more about the intended application will help.

Or I may be totally misreading what you're trying to do.

Link to comment
Share on other sites

Thanks, folks, but I'm still stuck.

Qie Niangao

I have a dozen lists, with lengths, each list is a different sequence of animations.
(I have a working demo of each individual list that runs through a HUD - with a dozen buttons -  but I want to change it to "chat  controlled" because the HUD is getting big.)
I want to use the parsed word in the middle of the chat, assigned the name "action", to chose which one of those dozen lists to run.
The first thing  I need to do is find out the number of items in the list (length) so I can sequence through them using something like this...
{
integer i = ++gCount;
if (i)
llStopAnimation(llList2String(action,i-1));
if (i < length)
llStartAnimation(llList2String(action, i));
}
but I can't even get started because I can't find "length" ... and I'm guessing I'm not finding my list at all.

I don't know if I've answered your question. I'm new to this.
I've never tried to access a list by chat. (Currently each list is in a seperate button/script on an ugly HUD.)
How do I use the float ("action") that I chat ("first", "second", etc), to get the list (named "first", "second", etc)?

Ela Talaj

Substituting "llStringLength" gives me the lenght of the input string not the list of the same name
    "first" gives "5" (the number of letters in "first") not 8 (the lenght of the list)
    "second" gives "6" not 12


Link to comment
Share on other sites

You get the point...

 

It makes SEVERAL YEARS since the beginning of mono that Linden has promised us new types because it would be easier for Linden to implement new features of language  in Mono .

It makes SEVERAL YEARS there are no evolutions of the language for something more clever .

 

 

So , clearly , you have ZERO solution to solve efficiently your problem . 

 

 

Nevertheless ,you can always use a totally crappy and inneficient  code in changing the structure of the datas .

For instance , you could merge all your lists in a big one , and build an another list who references their names and their positons in the merged list . It s of course some bull**bleep** because you manipulate bigger lists ;. And as ther accessors set/get list are not linear time with the lenght of the list , it will make your code laggier.

Nvertheles if you think it s useful ... 

 

For instance , you could use  this :

 

list singletonRegisteredLists;list singletonDictionnaryRegisteredLists;errorOutput(string s){    llRegionSayTo(llGetOwner(), PUBLIC_CHANNEL , "ERROR  :" +  llGetScriptName() + " " + s);   }infoOutput(string s){    llRegionSayTo(llGetOwner(), PUBLIC_CHANNEL , "INFO  :" +  llGetScriptName() + " " + s);      }registerList(list dataList, string nameList){    if ( llListFindList( singletonDictionnaryRegisteredLists , (list)nameList ) != -1 )    {        errorOutput( "This name of list is already registered . Call update the list or change the name of the list");    }    else    {        integer i = llGetListLength(singletonRegisteredLists);        singletonRegisteredLists += dataList;        singletonDictionnaryRegisteredLists += [ nameList, i, i+llGetListLength(dataList)];    }}list getListFromRegistered(string nameList){    integer idx = llListFindList( singletonDictionnaryRegisteredLists , (list)nameList );    if ( idx == -1 )    {       errorOutput( "The name of the list is not existing in the dictionnary" );        return [];    }    else    {        return llList2List(singletonRegisteredLists, llList2Integer(singletonDictionnaryRegisteredLists, idx + 1) , llList2Integer(singletonDictionnaryRegisteredLists, idx + 2) );    }}    integer getListLengthFromRegistered(string nameList){    list local = getListFromRegistered(nameList);    integer lengthLocal =  llGetListLength(local);    local = [];    return lengthLocal;}default{    on_rez(integer start_param)     {        llResetScript();    }            state_entry()    {        list first = ["antimony", "arsenic", "aluminum", "selenium", "hydrogen", "oxygen", "nitrogen", "rhenium"];        list second = ["nickel", "neodymium", "neptunium", "germanium", "iron", "americium", "ruthenium", "uranium", "Europium", "zirconium", "lutetium", "vanadium"];        list third = ["plutonium", "argent" ];            registerList(first, "first");            registerList(second, "second");        registerList(third, "third");        llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);    }    run_time_permissions(integer perm)    {        if(PERMISSION_TRIGGER_ANIMATION & perm)        {              infoOutput( " has PERMISSION_TRIGGER_ANIMATION perms for  "+(string)llGetPermissionsKey());               llSetTimerEvent(2); //Cause the timer event to be triggered a maximum of once every 2 seconds.         }        if (perm == 0)        {            errorOutput( " has NO perms for  "+ (string)llGetPermissionsKey());        }        llListen( 0, "", "", "" );     }            listen(integer channel, string name, key id, string message)    {        list input = llParseString2List(message, [" "], []); //the input is three variables, separated by spaces("song first 3")        llSay(0, (string)input); //checks to see if its heard me by repeating what I said. It does. It works. The next three “llSay”s prove the Parsing workes. It does.        string gate = llList2String(input, 0) ; // “gate” assures that only a message starting with the “magic word” will initiate the animations.        string action =  llList2String(input, 1);  // “action” is the name of the list that contains the name of the animations. From this, also, my problem starts.        string level =  llList2String(input, 2);  // “level” is an integer will control the “action” (maybe – still in the planning stage:         llSay(0, (string)gate); // works = repeats the magic word        llSay(0, (string)action);// works = says the name of the list;first” or “second”        llSay(0, (string)level); // works = repeats the integer        if (gate == "off") // when told "off"..        {            llSay (0, "bye.");            llResetScript();        } //OK, but trouble then starts (next)        else if (llList2String(input, 0) == "song")  //assures chat starts with         {                        list listAction = getListFromRegistered(action);            llOwnerSay("The list selected is :" + llList2CSV(listAction));            integer length = llGetListLength(listAction); // Error : Function call mismatches type or number of arguments            llOwnerSay("The numbe of elements of the list selected is  :" + (string)llGetListLength(listAction));                   }    }}

 

Link to comment
Share on other sites

Exactly. FWIW, I did much the same thing using a notecard as input, to avoid duplicating the lists and the strings they contain. It's uglier for not hiding the indexing (or "registration") in helper functions, but in case it's of interest:

list actions;   // strided list of action names and their corresponding indices into animations list// e.g., [ first_action_name, 0, second_action_name, 10, ...] for a first action with ten animslist animations;    // one long list of animation names, indexed in the actions liststring notecardName;integer notecardLine;key notecardQuery;// Don't end the notecard with a blank line (handling that would make this (more) confusing)default{    state_entry()    {        notecardName = llGetInventoryName(INVENTORY_NOTECARD, 0);         // Assuming only one notecard in object inventory        notecardQuery = llGetNotecardLine(notecardName, notecardLine = 0);    }    dataserver(key queryid, string data)    {        if (queryid != notecardQuery)            return; // not for us        if (EOF != data)        {            // request next line:            notecardQuery = llGetNotecardLine(notecardName, ++notecardLine);             // process this line, an action name followed by animations            list dataList = llParseString2List(data, ["|"], []);            actions +=                 [ llStringTrim(llList2String(dataList, 0), STRING_TRIM) // action name                , llGetListLength(animations)  // index to these anims in animations list                ];            integer dataListLength = llGetListLength(dataList);            integer dataListIdx;            while (++dataListIdx < dataListLength)                  animations += llStringTrim(llList2String(dataList, dataListIdx), STRING_TRIM);        }        else    // done reading notecard            llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);    }    run_time_permissions(integer perms)    {        // llOwnerSay("FYI, actions = ["+llDumpList2String(actions, ", ")+"]");        if (PERMISSION_TRIGGER_ANIMATION & perms)            llListen(0, "", llGetPermissionsKey(), "");        // else might warn about bad perms    }    listen(integer channel, string name, key id, string message)    {        list input = llParseString2List(message, [" "], []); //the input is three variables, separated by spaces("song first 3")        string gate = llList2String(input, 0);        string actionName =  llList2String(input, 1);         string level =  llList2String(input, 2);        if (gate == "off") // when told "off"..        {            llSay (0, "bye.");            llResetScript();        }        else         if (llList2String(input, 0) == "song")        {            integer actionsIdx = llListFindList(actions, [actionName]);            if (-1 == actionsIdx)            {                llRegionSayTo(id, 0, "No such song as '"+actionName+"'");                return;            }            integer animsIdx = llList2Integer(actions, actionsIdx + 1);            integer animCount;  // Number of anims associated with this action            if (actionsIdx + 2 >= llGetListLength(actions))  // last action                animCount = llGetListLength(animations)-animsIdx;   // so all the rest are our anims            else    // not the last, so our anims only go up to where the next action's starts                animCount = llList2Integer(actions, actionsIdx+3) - animsIdx;            list animsForThisAction = llList2List(animations, animsIdx, animsIdx + animCount - 1);            llOwnerSay("\nFYI, song "+actionName+" has "+(string)animCount+" animations :\n\t"                + llDumpList2String(animsForThisAction, "\n\t"));        }    }}

 which would operate on notecards that look like:

first | antimony | arsenic | aluminum | selenium | hydrogen | oxygen | nitrogen | rheniumsecond | nickel | neodymium | neptunium | germanium | iron | americium | ruthenium | uranium | Europium | zirconium | lutetium | vanadium

 

Link to comment
Share on other sites

Wow, these notecards look to be a useful resources but it will take me a while to learn these new commands, etc.
But I will learn them, eventually.
Meanhwile, I've been working on my script in my old fashion (no notecard) way and almost have it working but can't "transplant" the "timer()". I'll post a new thread about that tonight.

Link to comment
Share on other sites

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