Jump to content

Parsing list from object description


Tighern McDonnell
 Share

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

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

Recommended Posts

So.... I have a "repair" script in an object that is listening for a set of tools (messages) in an order. I would like to make it easily editable so that the end user can select the order of tools used. I am currently trying to have a "list" in the object description in an example "S,M,P,F" - the script will then take the number or letter code and turn it into the message that designated tool will "say". I can use that variable in the "IF" statement to make sure the tool used is the right one. I am having a hard time taking the llList2string(gOrder, 0) and turning it from "S" into string gTool1 = "SpannerP... I am sure it is simple and I am just missing something. I hope this is clear enough to figure out.

Link to comment
Share on other sites

5 hours ago, Tighern McDonnell said:

I am having a hard time taking the llList2string(gOrder, 0) and turning it from "S" into string gTool1 = "SpannerP... 

Maybe I'm just tired, but this makes little sense as far as describing the problem.

What is the relation between S and SpannerP? Does S stand for Spanner or something else? What about the other letters?

Why isn't this okay? (Sorry, posting from mobile and can't use the code block)

If( llList2String(gOrder, 0) == "S" )

{

    string gTool1 = "SpannerP";

}

If I'm understanding correctly and you want to convert the single letters into full names or commands, you would end up with a lot of IF statements this way..

  • Like 1
Link to comment
Share on other sites

5 hours ago, Tighern McDonnell said:

So.... I have a "repair" script in an object that is listening for a set of tools (messages) in an order. I would like to make it easily editable so that the end user can select the order of tools used. I am currently trying to have a "list" in the object description in an example "S,M,P,F" - the script will then take the number or letter code and turn it into the message that designated tool will "say". I can use that variable in the "IF" statement to make sure the tool used is the right one. I am having a hard time taking the llList2string(gOrder, 0) and turning it from "S" into string gTool1 = "SpannerP... I am sure it is simple and I am just missing something. I hope this is clear enough to figure out.

It sounds like you want to do a lookup so that S = Spanner, M = Mallet, P = Plunger and so on.

 

One solution is to have a strided list consisting of the abbreviation and the tool name. You then step through the list looking at entries 0, 2, 4, 6.. and when you find a match you taken the next entry after the matching one.

list tools = ["S", "Spanner", "M", "Mallet", "P".,"Plunger"];

string findTool(string findMe)
{
	integer iiMax = llListLength(tools);
	integer ii;
	string found = "No Match";

	for( ii = 0; ii < iiMax; ii+= 2)
        {
                 if( llList2String(tools, ii) == findMe) found = llList2String(tools, ii+1);
         }

	return found;
}

Code typed on on the fly and not tested :) 

There is a quicker search method using llListFindList, which returns the index of the matching entry, but it is less explanatory and also wouldn't be reliable for a strided list where the search item might be elsewhere than the first stride.

Bear in mind when you are reading the object description that LSL can only access some of the field, as with notecard reads. You'll find this limit in the wiki entry for limitations.

Edited by Profaitchikenz Haiku
typos, what else?
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

I looks like the strided list may be the way to go. To explain even further... yes I want to be able to relate the "coded" numbers or letters in the description of an object to a "name" that a tool says... so the normal if statement would say in a listen event that IF (msg=="spanner") then do X... the tool will whisper "spanner" and i need to check the description list and compare it to the list of tools to see if that tool is the right one... I hope that makes more sense.

 

Link to comment
Share on other sites

5 hours ago, Tighern McDonnell said:

I hope that makes more sense

Yes, it does.  I suspect that most of us have our favorite way to deal with this situation.  Strided lists are often the best answer, but it's just as easy to run parallel lists and match their contents by using llListFindList to generate a list index for the specific entry that you are interested in.  I hop back and forth between the two methods, depending on my mood and the particular script.  I'm not much of a fan of JSON, but that's yet another possibility. 

  • Like 2
Link to comment
Share on other sites

so I am missing something... I decided to go with two lists instead of a strided list... I am using some code from the wiki and code I wrote... Please feel free to pick apart the entirety of the script. I am sure there is a much more efficient way of doing this whole thing and I hope you guys can understand what I am trying to do with it. The below code is not working correctly and I am not sure why. If the object is in default state, the listen will trigger to change to broken state. Once there it is listening for the tool to say its name on channel -9000... Using the variable string "CT" and having it "say" what it is... this seems to correlate to the right tool for the right step... but it does not advance the "step" integer... hopefully it is something simple I am missing and again im not too advanced with any of this so I am sure there is a much better way to do it.

 

//Version 0.0.3 for panel
//added chat command
integer step=1;
vector COLOR_RED = <1.0,0,0>;
vector COLOR_GREEN = <0,1,0>;
vector COLOR_WHITE = <1,1,1>;
float OPAQUE = 1.0;
float gTimer = 64800;
integer gListenA;
integer gListenB;
integer chana = 128;
integer chanb = -128;
string gIndex;
string CT ="ABC";
list glTools = ["Open","Polarity","Hypospray","Conduit","Tricorder","Spanner","ISO Chip","Fire Extenquisher","Torch","Micro-resonator","Fuse"];
list glCode = ["O","P","H","C","T","S","I","EF","To","M","F"];

tool_finder()
{
    list tools = llParseString2List(llGetObjectDesc(),[","],[]);
    string currenttool = (string)llList2String(tools,step - 1);
    integer gIndex = llListFindList(glCode, [currenttool]);
    if (gIndex != -1)
    {
        list three_four = llList2List(glCode, gIndex, gIndex + 1);
        string CT = (string)llList2String(glTools,gIndex);
        llOwnerSay(CT);
    }
}

default
{
    state_entry()
    {
//        llSetTimerEvent(gTimer);
        llSetText("Opperational",<0,1,0>,1);
        llSetColor(COLOR_WHITE,1);
        llMessageLinked( LINK_SET, 777, "STOP", NULL_KEY );
        gListenA = llListen(chana,"","","");
        gListenB = llListen(chanb,"","","");

    }

    listen(integer channel, string name, key id, string message)
    {
        if (message == "breakme")
        {
            state broken;
        }
    }

//    timer()
//    {
//        llMessageLinked( LINK_SET, 777, "START", NULL_KEY );
//        state broken;
//    }
}

state broken

{
    state_entry()
    {
        llListen(-9000, "", NULL_KEY, "");

        if (step==1)
        {
            llSetText("Broken\nStart with Spanner",COLOR_RED, OPAQUE);
            llMessageLinked( LINK_SET, 777, "START", NULL_KEY );
            llSetColor(COLOR_RED, 1);
        }
    }

    listen(integer chan, string name, key id, string msg)
    {

        if (1 == step)
        {
            tool_finder();
            if (msg == CT)
            {
            llSetText("Step " + (string)step + " completed move on to next step",<1.0,0.522,0.106>,OPAQUE);
            ++step;
            llWhisper(0,"Micro fractures present. Resonate material.");
            }
            else if (step != 1)
            {
                llWhisper(0,"That is the wrong tool. Becareful to not make this worse!");
                step = 1;
            }
        }

        else if (step == 2)
            {
                tool_finder();
                if (msg == CT)
        {
            
                llSetText("Step " + (string)step + " completed move on to next step",<1.0,0.863,0.0>,OPAQUE);
                ++step;
                llWhisper(0,"Please check the power polarity before replacing fuse.");
            }
            else if (step != 2)
            {
                llWhisper(0,"You made it to step " + (string)step + ". Now you need to start over for using the wrong tool");
                step = 1;
            }
        }

       else if (step == 3)
            {
                if (msg == CT)
        {
            
                llSetText("Step " + (string)step + " completed move on to next step",<.004,1.0,0.439>,OPAQUE);
                ++step;
                llWhisper(0,"Move on to " + (string)step);
            }
            else if (step != 3)
            {
                llWhisper(0,"Wrong Tool - Resetting");
                step = 1;
            }
        }

            else if (step == 4)
            {
                if (msg == CT)
                {

                llSetText("Repaired on " + llGetDate(),<0,1.0,0>,OPAQUE);
                llMessageLinked( LINK_SET, 777, "STOP", NULL_KEY );
                llWhisper(0,"Repair completed");
                step = 1;
                state default;
            }
            else if (step != 4)
            {
                llWhisper(0,"Wrong Tool - Resetting");
                step = 1;
            }
        }
        llOwnerSay("test " + msg);
    }
}

 

Link to comment
Share on other sites

Just at a quick glance, I notice that you have defined a local string variable CT in your user defined function, tool_finder().  That will not update the global variable with the same name, so it you are counting on knowing the global variable's current value, it will never change.

As a secondary matter, you can almost certainly compress the separate if conditions in the listen event of state broken into a much smaller single block of code.  Aside from being more aesthetically pleasing, the real value of doing that is that it will force you to think more carefully about exactly how list indices are handled at each step in your process.  If they are going to advance properly as the variable, step, increases, then the logic in each of the separate steps should be the same.  When you compress the various if conditions into a single block of code successfully, they will be, by definition.

It is very easy to get yourself lost in lists.  Lists start with index zero, not 1, but our human practice is to count 1, 2, 3, 4, ...  I find that it's easy to get my code scrambled if I accidentally start thinking like a human instead of a LSL driven machine.  That's yet another reason for compressing code as much as possible, to be sure that all similar processes in your script are using the correct updated values of key variables like CT and step.

Link to comment
Share on other sites

So I have been racking my brain about the actual formula code for this one. I see the hints toward using the index from the llFindListFind command and using it to correlate to the "step" and also looking at the "for" and "while"  but still cannot seem to get the right combination to get it to work. the one thing is I need each "step" effect to be slightly different as well... So a little more obvious of a place to look at examples similar to what I am trying to do. I am not asking somebody to write the code for me just point me to an example that is similar that i can learn from. 

Link to comment
Share on other sites

whats not clear from the script is what you trying to accomplish

you have a list of tools in Object description. Say : A,B,C,D

then you have a list of tools in glCode: Say: A,B,C,D,E,F,G,H

then a textual name for each tool in glTools: Say: Apple,Banana,Carrot, ... etc

whats not clear is what tool should be used when 'step' == 1, 2, etc

if you can tell us what the tool should be at each 'step' then we will be able to help you with the script

 

Link to comment
Share on other sites

5 hours ago, Tighern McDonnell said:

So I have been racking my brain about the actual formula code for this one. I see the hints toward using the index from the llFindListFind command and using it to correlate to the "step" and also looking at the "for" and "while"  but still cannot seem to get the right combination to get it to work. the one thing is I need each "step" effect to be slightly different as well... So a little more obvious of a place to look at examples similar to what I am trying to do. I am not asking somebody to write the code for me just point me to an example that is similar that i can learn from. 

The way ahead is to write out in brief sentences what you want to happen. Try to expand each simple sentence into a series of steps, and from there move to creating code.

If it helps with creating the sentences, imagine you are explaining to a friend how it is going to work.

Link to comment
Share on other sites

The if else statements are chaotic and can not work
example:

else if (step == 3) {
    if (msg == CT) {
        llSetText("Step " + (string)step + " completed move on to next step",<.004,1.0,0.439>,OPAQUE);
        ++step;
        llWhisper(0,"Move on to " + (string)step);
    }
    else if (step != 3) {
        llWhisper(0,"Wrong Tool - Resetting");
        step = 1;
    }
}

"if (step != 3)" will never become executed for example.

Make a plan and start with the steps

Step 1 - what is needed to get there? Where you can go from there under what conditions?
So you get a graph with some arrows and conditions for a start.

 

Link to comment
Share on other sites

It seems to me like you need to simply set up an integer at the top of the listen() event that gets initialized with the current tool every time listen() is triggered.

Don't forget that list indexes begin with 0.

Notice in this example script at the top of the listen() event.

step = llListFindList(steps, ...........

list steps = ["axe","hammer","rubber chicken"];
list actions = ["chops a tree.", "drives a nail.", "laughs really hard."];
integer step = 0;
integer lastStep = -1;

default
{
    on_rez(integer num)
    {
        llResetScript();
    }

    state_entry()
    {
        llListen(0,"",NULL_KEY,"");
        llSay (0, "Pick a tool.  Axe, hammer, or rubber chicken.");
    }

    listen(integer chan, string name, key id, string msg)
    {
        step = llListFindList(steps, [llToLower(llStringTrim(msg, STRING_TRIM))]);
        llOwnerSay ((string)step);
        string sayMe = "";
        
        if (step > -1) {
            if (step == 0) { //Don't forget...lists start with an index of 0 rather than one.
                sayMe = "";
                if (lastStep != -1) {
                    sayMe = "/me puts down the: "+(string)llList2String(steps,lastStep)+".\n";
                }
                sayMe += name+" picks up a battle axe and yells, \"There can be only one!\"";
                    
                llSay(0, sayMe);
            
                llSay(0, name+" "+llList2String(actions, step));
                
                lastStep = step;
            }

            else if (step == 1) {
                sayMe = "";
                if (lastStep != -1) {
                    sayMe = "/me puts down the: "+(string)llList2String(steps,lastStep)+".\n";
                }

                sayMe += name+" can't seem to find the hammer but this nail gun should work!\n"+
                        "Ooops, it's out of nails.  Those rolls from the school cafateria will do the job!";

                llSay(0, sayMe);
            
                llSay(0, name+" "+llList2String(actions, step));

                lastStep = step;
            }

            else if (step == 2) {
                    sayMe = "";
                    if (lastStep != -1) {
                        sayMe = "/me puts down the: "+(string)llList2String(steps,lastStep)+".\n";
                    }
                    
                    sayMe += name+" pulls out a rubber chicken.";
                    
                    llSay(0, sayMe);
                
                    llSay(0, name+" "+llList2String(actions, step));
                
                    lastStep = step;
            }
        }
    }
}

 

Link to comment
Share on other sites

You can also set things up like so:

 

if ( ~llListFindList(yourList, [incoming message])  ){do this}

The reason I don't do it that way in the previous example is to avoid searching the list again in every branch of the if tree.

 

In cases where you only need to get a list index once...it's actually more efficient than:

step = llListfindList();

if (step != -1)......

 

Link to comment
Share on other sites

 

On 11/15/2018 at 2:37 AM, Tighern McDonnell said:

So I have been racking my brain about the actual formula code for this one. I see the hints toward using the index from the llFindListFind command and using it to correlate to the "step" and also looking at the "for" and "while"  but still cannot seem to get the right combination to get it to work. the one thing is I need each "step" effect to be slightly different as well... So a little more obvious of a place to look at examples similar to what I am trying to do. I am not asking somebody to write the code for me just point me to an example that is similar that i can learn from. 

I'm rather confused about how this is supposed to work, so please forgive me if I've misunderstood, but as I understand it, the idea is that you have to complete a series of tasks, each involves attaching the correct object in sequence and looking up the matching abbreviation or code.   

If that's the case, the basic formula is something on these lines, but it's really not clear to me what decisions you want as a result of having this data:

		integer iIndex = llListFindList(glCode,[message]);//find index of message in the glCode list
		if(~iIndex){//if it's there (i.e. != -1)
			string sTool = llList2String(glTools,iIndex);//find the corresponding tool in the glTools list
			llOwnerSay("You are using the "+sTool+."  The next tool on the list is "+llList2String(glTools iIndex + 1));
			
		}
		else{
			llOwnerSay("Can't find "+message+" in glCode");
		}

 

Link to comment
Share on other sites

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