Jump to content

Notecard config reader with listener


MelodyClone1
 Share

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

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

Recommended Posts

Hi, I'm trying to write a notecard config reader that responds to the user's clicks on a HUD (like a sound board), but stuck on the part on how to combine a listen event (for the hud click) with looping through every line on the notecard. This is what I have so far:

key gOwnerKey = NULL_KEY;
string configurationNotecardName = "config";
key notecardQueryId;
integer line;
string button;
string message;
 
init()
{
    line = 0;
    notecardQueryId = llGetNotecardLine(configurationNotecardName, line);
}
 
processConfiguration(string data)
{
    if(data == EOF)
    {
        return;
    }
    if(data != "")
    {
    //  if the line does not begin with a comment
        if(llSubStringIndex(data, "#") != 0)
        {
            //  find first delimiter sign
            integer i = llSubStringIndex(data, ",");
 
            //  if line contains delimiter sign
            if(i != -1)
            {
                list parsedLine = llParseString2List(data,[","],[]);
                button = llList2String(parsedLine,0); //set "button" to the line in the notecard
                message = llList2String(parsedLine,1); //set "message" to the line in the notecard
            }
        }
    }
//  read the next line
    notecardQueryId = llGetNotecardLine(configurationNotecardName, ++line);
}
 
default
{
    state_entry()
    {
        gOwnerKey = llGetOwner();
        integer channel_dialog = 9999;
        llListen(channel_dialog, "", NULL_KEY, "");
    }
    listen(integer chan, string name, key id, string msg) //listen for a hud click on channel 9999
    {
        list hudclick = llParseString2List(msg, ["|"],[]);
        string name = llList2String(hudclick,1); //name of button clicked on hud
        string desc = llList2String(hudclick,2); //desc of button clicked on hud
 
        init(); //begin notecard reading
       
        if(llGetListLength(hudclick)>1)
        {
            key HUDowner = llList2Key(hudclick,0);
            if(HUDowner == gOwnerKey)
            {
                if (name == button) //if what you clicked on the hud matches with "button" value in notecard
                {
                    llOwnerSay(message);
                }
                //repeat for every notecard line
                ...
            }
        }
    }
    dataserver(key request_id, string data)
    {
        if(request_id == notecardQueryId)
            processConfiguration(data);
    }
}

 

Sample config notecard:

==========================
NOTECARD SAMPLE
==========================
 
button1,It's sunny today
button1,Let's head outside
button2,It's raining today
button2,Let's stay inside
 
#so if you click "button1" on HUD it should result in
#llOwnerSay("It's sunny today");
#llOwnerSay("Let's head outside");

 

Thanks.

Edited by MelodyClone1
Link to comment
Share on other sites

You may be making the job unnecessarily difficult by expecting the script to read the notecard every time that you click the HUD.  It would be easier to read the entire notecard once when triggered by a state_entry or a changed event, feed its contents into a list, and then query the list when you click a button.

Link to comment
Share on other sites

1 hour ago, Rolig Loon said:

You may be making the job unnecessarily difficult by expecting the script to read the notecard every time that you click the HUD.  It would be easier to read the entire notecard once when triggered by a state_entry or a changed event, feed its contents into a list, and then query the list when you click a button.

But what's the best way to compile the notecard into a list if there are multiple lines in the notecard? Wouldn't I need a separate list for every single line in the notecard? For example if my notecard looked like this, I'd need 7 lists to store it, then do a lookup against index 0 of each list for the "button" name?

button1,1
button1,2
button2,3
button2,4
button3,5
button4,6
button4,7

 

Edited by MelodyClone1
Link to comment
Share on other sites

The complexity does go up if you have a huge number of notecard lines, yes.  Still, the basic idea is fairly straightforward.  You trigger the dataserver event with llGetNotecardLine(strMyCard, iLine=0) in your state_entry or changed event and then let the dataserver event stuff everything from the notecard into a list....

dataserver (key id, string data)
{
    if (id == kReadCard)
    {
        if (data != EOF)
        {
            lMy_list += [data];    // Add the current notecard line's contents to the list
            kReadCard = llGetNotecardLine(strMyCard, ++iLine);    // Read the next line
        }
        else
        {
            llSay(0, llList2CSV(lMy_list));    // Just to see what's in the list you just created ....
        }
    }
}

       So, you only have to do that once.  Thereafter, you tell your touch_start event to grab the appropriate list element each time someone touches a button...

touch_start (integer num)
{
    integer idx = llListFindList( [ button1, button2, button3, button4 ], [ llDetectedLinkNumber(0) ] );    
    llSay(0, llList2String(lMy_list, idx));
}

where button1, button2, button3, button4, .... are the link numbers of your HUD buttons.  

 

Link to comment
Share on other sites

Issue with that is there are multiple occurrences of "button1" (for example), and I think llListFindList would only find the first occurrence? Wouldn't this only return "1", instead of "1" and "2"? I'd need to somehow combine the line-by-line parsing:

myList += [data];
notecardQueryId = llGetNotecardLine(configurationNotecardName, ++Line);

with the lookup part:

integer idx = llListFindList( [ button1, button2, button3, button4 ], [ llDetectedLinkNumber(0) ] );    

because I assume myList would end up looking like this:

["button1,1","button1,2","button2,3","button2,4","button3,5","button4,6","button4,7"]

so that it would only stop looping once it no longer finds any "button1" in the list anymore.

This is why I wanted to combine the notecard parsing part with the listen event so that:

1. Get the name of the button that we clicked on the hud, which is a separate object, through listen event, since the hud simply uses llSay(9999,buttonclicked)
2. Start parsing notecard line by line. Add each line of notecard to a list myList
3. If buttonclicked == myList[0], do something
4. Move onto next line and repeat steps 2-4

but I wasn't sure how to get dataserver inside a listen event cause it should only start reading the notecard after we receive the buttonclicked from listen event.

Edited by MelodyClone1
Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

I don't understand.  Why would there be multiple instances of "button1" on the same HUD?  

It's not multiple instances of "button1" on the HUD, it's multiple instances of it in the notecard:

button1,1
button1,2
button2,3
button2,4
button3,5
button4,6
button4,7

The HUD would be something like:

[button1]
[button2]
[button3]
[button4]

Obviously a simplified example as my config notecard won't just have integers, but if I click on "button1" in the HUD I'd want to return:

1
2

 

Edited by MelodyClone1
Link to comment
Share on other sites

Oh, I think I see.  In that case, the only real change is that instead of creating a simple list, you create a strided list with each stride referring to the data that are associated with a separate button. So, your list would be

lMy_list = [1,2,3,4,5,0,6,7];

in which there are four strides of two entries each.  The first two (1, 2,) are associated with button1, the second (3,4) is associated with button2, the third (5,0) is associated with button3, and the final set  (6,7) is associated with button4.  The interesting one is the third set, which only has one "real" entry.  The second one (0) is simply a filler to be ignored when it is called up. ( Or you could make that stride equal to (5,5), in which case you are using the entry twice, simply to make all strides have the same number of entries).  

Link to comment
Share on other sites

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