Jump to content

Dance machine script problem


Tattooshop
 Share

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

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

Recommended Posts

Hello! I have a single dance machine animator script, but it works a little incorrectly. when I add the first animation it gives an error "llDialog: must supply a message" if I click it, when I add the second - menu shows only one animation. and so on, one animation is always missing. what's wrong with it? (sorry for the long script)

integer i = 0;
integer chat_channel()
{
    return (integer)("0x" + llGetSubString(llMD5String((string) llGetOwner(), 1), 0, 6)) - 479;
}
integer total_dances = 0;
integer dance_number = -1;
integer page = 1;
integer page_dances = 0;
integer dance_starter = 0;
list dances_list = [];
list dance_buttons = [];
string dances_text_list = "";
string exclude_first_page = "";
string exclude_last_page = "";

// Stop all dancing animations function, one by one
stopAllDances()
{
    i = 0;
    while (i < total_dances)
    {
        if (llList2String(dances_list, i) != "")
        {
            llStopAnimation(llList2String(dances_list, i));
        }
        ++i;
    }
}

// Build dances list (text for dialog, buttons for options) for user depending on selected page and send it via dialog box
// If the page is last or first use "---" instead of button with page number - detect this via counting overall dances list or check if the current dances list is < than 9
showMenu(key userTouched, integer page)
{
    
    if (page > 1)
    {
        dance_starter = (page * 9) - 9;
    }
    else
    {
        dance_starter = 0;
    }
    
    page_dances = 0;
    dance_buttons = [];
    dances_text_list = "";
    
    while (page_dances < 9)
    {
        if (llList2String(dances_list, dance_starter) != "")
        {
            dance_buttons = (dance_buttons = []) + dance_buttons + (string) dance_starter;
            dances_text_list = (dances_text_list = "") + dances_text_list + (string)(dance_starter) + ") " + llList2String(dances_list, dance_starter) +
                "\n";
        }
        ++page_dances;
        ++dance_starter;
    }
    
    if (page == 1)
    {
        exclude_first_page = "---";
    }
    else
    {
        exclude_first_page = "PAGE " + (string)(page - 1);
    }
    
    if (llGetListLength(dance_buttons) < 9 || (page * 9) >= total_dances)
    {
        exclude_last_page = "---";
    }
    else
    {
        exclude_last_page = "PAGE " + (string)(page + 1);
    }
    
    dance_buttons = (dance_buttons = []) + "STOP DANCE" + exclude_first_page + exclude_last_page + dance_buttons;
    llDialog(userTouched, dances_text_list, dance_buttons, chat_channel());
}

// String cutter function
string stristr(string haystack, string needle, integer after_needle)
{
    if (haystack)
    { //we have a haystack, it's not ""
        //Now find us a needle!
        integer pos = llSubStringIndex(haystack, needle);
        if (~pos)
        { //We have found a needle!
            if (after_needle) //return what comes after needle
                return llGetSubString(haystack, pos + llStringLength(needle), -1);
            return llDeleteSubString(haystack, pos, -1);
        }
    }
    return "";
}

// Search for a word in string function
integer like(string value, string mask)
{
    integer tmpy = (llGetSubString(mask, 0, 0) == "%") |
        ((llGetSubString(mask, -1, -1) == "%") << 1);
    if (tmpy)
        mask = llDeleteSubString(mask, (tmpy / -2), -(tmpy == 2));
    
    integer tmpx = llSubStringIndex(value, mask);
    if (~tmpx)
    {
        integer diff = llStringLength(value) - llStringLength(mask);
        return ((!tmpy && !diff) ||
            ((tmpy == 1) && (tmpx == diff)) ||
            ((tmpy == 2) && !tmpx) ||
            (tmpy == 3));
    }
    return FALSE;
}

// Execute script, main part
default
{
    
    // Reset script at object rezz
    on_rez(integer start_param)
    {
        llResetScript();
    }
    
    // Crawl through dances and load them all to the list at script start / reset only to save region CPU power
    // Builded list will be later just called at touch/page reload, not rebuilded like in original work
    // Start listening to the unique channel for commands
    state_entry()
    {
        total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list = (dances_list = []) + dances_list + (string) llGetInventoryName(INVENTORY_ANIMATION, ++i);
        }
        llListen(chat_channel(), "", NULL_KEY, "");
    }
    
    // Show menu at touch to the person who touched object, page 1
    touch_start(integer total_number)
    {
        showMenu(llDetectedKey(0), 1);
    }
    
    // Automatiacally reset whole script if dance was added or removed from object's inventory
    // So you don't must to use "reset script" in your viewer, when you add something new
    changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
    
    // Get dance from user interaction and start dance, stop dance or send next page
    listen(integer channel, string name, key id, string message)
    {
        if (message == "STOP DANCE")
        {
            dance_number = -1;
            llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
        }
        else if (like(message, "PAGE%"))
        {
            showMenu(id, (integer) stristr(message, "PAGE ", TRUE));
        }
        else if (message == "---")
        {
            // Do nothing here
        }
        else
        {
            dance_number = (integer) message;
            llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
        }
    }
    
    // Ask for permissions and change dances
    // If dance number is under 0, then just stop dancing without calling any new animation
    run_time_permissions(integer perms)
    {
        if (perms & PERMISSION_TRIGGER_ANIMATION)
        {
            stopAllDances();
            if (dance_number > -1)
            {
                llStartAnimation(llList2String(dances_list, dance_number));
            }
        }
    }
}

 

Edited by Tattooshop
Link to comment
Share on other sites

Your problem is right here

        i = 0;
        while (i < total_dances)
        {
            dances_list = (dances_list = []) + dances_list + (string) llGetInventoryName(INVENTORY_ANIMATION, ++i);
        }

If you do it that way, you are always updating i before you need to.  You'll never see llGetInventoryName(INVENTORY_ANIMATION, 0), and your script will try to load a non-existent final animation labeled llGetInventoryName(INVENTORY_ANIMATION, total_dances).  Always watch your list indices.   The best way to find error like this is to include a test statement that says

llOwnerSay(llList2CSV(dances_list));

after you think you have loaded the list, just to see what's really in it.

EDIT:  BTW, you really don't need to do that business of dances_list = (dances_list = []) + dances_list +...   Just write

dances_list += [ llGetInventoryName(INVENTORY_ANIMATION, i)];

Edited by Rolig Loon
You don;t need to typecast llGetInventoryName either. It's already a string
  • Thanks 1
Link to comment
Share on other sites

39 minutes ago, Rolig Loon said:

Your problem is right here


        i = 0;
        while (i < total_dances)
        {
            dances_list = (dances_list = []) + dances_list + (string) llGetInventoryName(INVENTORY_ANIMATION, ++i);
        }

Just write

 

dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];

Thank you very much for your answer! So I simply replaced the line, but I did something wrong and it do not respond on click at all :(

    state_entry() {
        total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while(i < total_dances) 
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
        }
        llListen(chat_channel(), "", NULL_KEY, "");
    }

 

Link to comment
Share on other sites

2 minutes ago, Tattooshop said:

So I simply replaced the line, but I did something wrong and it do not respond on click at all

Oh, well, you have the same problem elsewhere.  Look at your touch_start event.  It's calling 

        showMenu(llDetectedKey(0), 1);

but what you really want it to do is show you the first page of menu entries, which is page ZERO:

showMenu(llDetectedKey(0),0);

Lists start with index 0, and your showMenu routine is specifically looking for the first page with

if (page > 1)
    {
        dance_starter = (page * 9) - 9;
    }

    else
    {
        dance_starter = 0;  // <<< See?
    }
  • Thanks 1
Link to comment
Share on other sites

37 minutes ago, Rolig Loon said:

Oh, well, you have the same problem elsewhere.  Look at your touch_start event.  It's calling 


        showMenu(llDetectedKey(0), 1);

but what you really want it to do is show you the first page of menu entries, which is page ZERO:

showMenu(llDetectedKey(0),0);

Lists start with index 0, and your showMenu routine is specifically looking for the first page with


if (page > 1)
    {
        dance_starter = (page * 9) - 9;
    }

    else
    {
        dance_starter = 0;  // <<< See?
    }

I replaced everything that is possible, tried to change ones to zeros, but the script does not respond and after some time gives an error. what am i doing wrong? 🤔

I removed comments lines to make script look shorter :D

integer i = 0;
integer chat_channel()
{
    return (integer)("0x" + llGetSubString(llMD5String((string) llGetOwner(), 1), 0, 6)) - 479;
}
integer total_dances = 0;
integer dance_number = -1;
integer page = 1;
integer page_dances = 0;
integer dance_starter = 0;
list dances_list = [];
list dance_buttons = [];
string dances_text_list = "";
string exclude_first_page = "";
string exclude_last_page = "";

stopAllDances()
{
    i = 0;
    while (i < total_dances)
    {
        if (llList2String(dances_list, i) != "")
        {
            llStopAnimation(llList2String(dances_list, i));
        }
        ++i;
    }
}

showMenu(key userTouched, integer page)
{
    
    if (page > 0)
    {
        dance_starter = (page * 9) - 9;
    }
    else
    {
        dance_starter = 0;
    }
    
    page_dances = 0;
    dance_buttons = [];
    dances_text_list = "";
    
    while (page_dances < 9)
    {
        if (llList2String(dances_list, dance_starter) != "")
        {
            dance_buttons = (dance_buttons = []) + dance_buttons + (string) dance_starter;
            dances_text_list = (dances_text_list = "") + dances_text_list + (string)(dance_starter) + ") " + llList2String(dances_list, dance_starter) +
                "\n";
        }
        ++page_dances;
        ++dance_starter;
    }
    
    if (page == 1)
    {
        exclude_first_page = "---";
    }
    else
    {
        exclude_first_page = "PAGE " + (string)(page - 1);
    }
    
    if (llGetListLength(dance_buttons) < 9 || (page * 9) >= total_dances)
    {
        exclude_last_page = "---";
    }
    else
    {
        exclude_last_page = "PAGE " + (string)(page + 1);
    }
    
    dance_buttons = (dance_buttons = []) + "STOP DANCE" + exclude_first_page + exclude_last_page + dance_buttons;
    llDialog(userTouched, dances_text_list, dance_buttons, chat_channel());
}

string stristr(string haystack, string needle, integer after_needle)
{
    if (haystack)
    { 
        integer pos = llSubStringIndex(haystack, needle);
        if (~pos)
        {
            if (after_needle)
                return llGetSubString(haystack, pos + llStringLength(needle), -1);
            return llDeleteSubString(haystack, pos, -1);
        }
    }
    return "";
}

integer like(string value, string mask)
{
    integer tmpy = (llGetSubString(mask, 0, 0) == "%") |
        ((llGetSubString(mask, -1, -1) == "%") << 1);
    if (tmpy)
        mask = llDeleteSubString(mask, (tmpy / -2), -(tmpy == 2));
    
    integer tmpx = llSubStringIndex(value, mask);
    if (~tmpx)
    {
        integer diff = llStringLength(value) - llStringLength(mask);
        return ((!tmpy && !diff) ||
            ((tmpy == 1) && (tmpx == diff)) ||
            ((tmpy == 2) && !tmpx) ||
            (tmpy == 3));
    }
    return FALSE;
}

default
{
    
    on_rez(integer start_param)
    {
        llResetScript();
    }
    
    state_entry()
    {
        total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
        }
        llListen(chat_channel(), "", NULL_KEY, "");
    }
    
    touch_start(integer total_number)
    {
        showMenu(llDetectedKey(0), 0);
    }
    
    changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
    
    listen(integer channel, string name, key id, string message)
    {
        if (message == "STOP DANCE")
        {
            dance_number = -1;
            llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
        }
        else if (like(message, "PAGE%"))
        {
            showMenu(id, (integer) stristr(message, "PAGE ", TRUE));
        }
        else if (message == "---")
        {
            // Do nothing here
        }
        else
        {
            dance_number = (integer) message;
            llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
        }
    }
    
    run_time_permissions(integer perms)
    {
        if (perms & PERMISSION_TRIGGER_ANIMATION)
        {
            stopAllDances();
            if (dance_number > -1)
            {
                llStartAnimation(llList2String(dances_list, dance_number));
            }
        }
    }
}

 

Link to comment
Share on other sites

5 minutes ago, Tattooshop said:

I replaced everything that is possible, tried to change ones to zeros, but the script does not respond and after some time gives an error. what am i doing wrong? 🤔

At this point, it's hard to tell from a distance. You're working with a script that someone else wrote (and so am I), and I can't test the thing.  But you can. I suggest two steps.  First, clarify what that error message is telling you.  That's at least a place to start.  Second, start putting diagnostic llOwnerSay statements in key places to find out what the script is actually doing, as opposed to what you think it is doing. I have pointed out a couple of obvious things that needed attention, but only you can do the rest of the sleuthing from here on. 

(Parenthetically, this is one of the reasons why it's usually a good idea to write your own scripts instead of using someone else's.  If you write a script, you know why you did each little thing, even if you did it wrong.  You can usually follow your own logic better than some stranger's.  Not only that, but you can't ever trust that the other scripter didn't make his own mistakes, which you have now inherited.)

Of course, someone else with a fresh pair of eyes may wander in here and see something that I haven't ..... 😉

  • Thanks 1
Link to comment
Share on other sites

        total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
        }
        llListen(chat_channel(), "", NULL_KEY, "");

you don't increase i so the loop will run forever and the script will never process any events.

your loop needs to go from 0 to total_dances-1 and requires an increment of i in each round.
There are several possibilities to make a loop:
http://wiki.secondlife.com/wiki/User:Kireji_Haiku/How_to_deal_with_lists_in_LSL

 

  • Thanks 1
Link to comment
Share on other sites

7 minutes ago, Nova Convair said:

you don't increase i so the loop will run forever and the script will never process any events.

your loop needs to go from 0 to total_dances-1 and requires an increment of i in each round.

Thank you, Nova.  I didn't go back to check that he was still incrementing i.  Nice catch,

Link to comment
Share on other sites

2 minutes ago, Tattooshop said:

Is the problem so serious?

Serious?  No, just an oversight.  I should have spotted that you left that part out.  Your original script incremented i by putting ++i inside the llGetScriptName function, so it was increasing the value before asking for the name of the animation.  You still need to increment i, as Nova pointed out.  You have to increment i after you get the current animation name, so the loop is ready to look for the next one.  So:

total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
            ++i;   //<< Increment HERE
        }
        llListen(chat_channel(), "", NULL_KEY, "");
  • Thanks 1
Link to comment
Share on other sites

9 hours ago, Rolig Loon said:

Serious?  No, just an oversight.  I should have spotted that you left that part out.  Your original script incremented i by putting ++i inside the llGetScriptName function, so it was increasing the value before asking for the name of the animation.  You still need to increment i, as Nova pointed out.  You have to increment i after you get the current animation name, so the loop is ready to look for the next one.  So:


total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
            ++i;   //<< Increment HERE
        }
        llListen(chat_channel(), "", NULL_KEY, "");

 

10 hours ago, Nova Convair said:

        total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
        }
        llListen(chat_channel(), "", NULL_KEY, "");

you don't increase i so the loop will run forever and the script will never process any events.

your loop needs to go from 0 to total_dances-1 and requires an increment of i in each round.
There are several possibilities to make a loop:
http://wiki.secondlife.com/wiki/User:Kireji_Haiku/How_to_deal_with_lists_in_LSL

 

Thank you both very much! Now everything works as it should! :)

integer i = 0;
integer chat_channel()
{
    return (integer)("0x" + llGetSubString(llMD5String((string) llGetOwner(), 1), 0, 6)) - 479;
}
integer total_dances = 0;
integer dance_number = -1;
integer page = 1;
integer page_dances = 0;
integer dance_starter = 0;
list dances_list = [];
list dance_buttons = [];
string dances_text_list = "";
string exclude_first_page = "";
string exclude_last_page = "";

stopAllDances()
{
    i = 0;
    while (i < total_dances)
    {
        if (llList2String(dances_list, i) != "")
        {
            llStopAnimation(llList2String(dances_list, i));
        }
        ++i;
    }
}

showMenu(key userTouched, integer page)
{
    
    if (page > 0)
    {
        dance_starter = (page * 9) - 9;
    }
    else
    {
        dance_starter = 0;
    }
    
    page_dances = 0;
    dance_buttons = [];
    dances_text_list = "";
    
    while (page_dances < 9)
    {
        if (llList2String(dances_list, dance_starter) != "")
        {
            dance_buttons = (dance_buttons = []) + dance_buttons + (string) dance_starter;
            dances_text_list = (dances_text_list = "") + dances_text_list + (string)(dance_starter) + ") " + llList2String(dances_list, dance_starter) +
                "\n";
        }
        ++page_dances;
        ++dance_starter;
    }
    
    if (page == 1)
    {
        exclude_first_page = "---";
    }
    else
    {
        exclude_first_page = "PAGE " + (string)(page - 1);
    }
    
    if (llGetListLength(dance_buttons) < 9 || (page * 9) >= total_dances)
    {
        exclude_last_page = "---";
    }
    else
    {
        exclude_last_page = "PAGE " + (string)(page + 1);
    }
    
    dance_buttons = (dance_buttons = []) + "STOP DANCE" + exclude_first_page + exclude_last_page + dance_buttons;
    llDialog(userTouched, dances_text_list, dance_buttons, chat_channel());
}

string stristr(string haystack, string needle, integer after_needle)
{
    if (haystack)
    {
        integer pos = llSubStringIndex(haystack, needle);
        if (~pos)
        {
            if (after_needle)
                return llGetSubString(haystack, pos + llStringLength(needle), -1);
            return llDeleteSubString(haystack, pos, -1);
        }
    }
    return "";
}

integer like(string value, string mask)
{
    integer tmpy = (llGetSubString(mask, 0, 0) == "%") |
        ((llGetSubString(mask, -1, -1) == "%") << 1);
    if (tmpy)
        mask = llDeleteSubString(mask, (tmpy / -2), -(tmpy == 2));
    
    integer tmpx = llSubStringIndex(value, mask);
    if (~tmpx)
    {
        integer diff = llStringLength(value) - llStringLength(mask);
        return ((!tmpy && !diff) ||
            ((tmpy == 1) && (tmpx == diff)) ||
            ((tmpy == 2) && !tmpx) ||
            (tmpy == 3));
    }
    return FALSE;
}

default
{
    
    on_rez(integer start_param)
    {
        llResetScript();
    }
    
    state_entry()
    {
        total_dances = llGetInventoryNumber(INVENTORY_ANIMATION);
        i = 0;
        while (i < total_dances)
        {
            dances_list += [(string) llGetInventoryName(INVENTORY_ANIMATION, i)];
            ++i;
        }
        llListen(chat_channel(), "", NULL_KEY, "");
    }
    
    touch_start(integer total_number)
    {
        showMenu(llDetectedKey(0), 0);
    }
    
    changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llResetScript();
        }
    }
    
    listen(integer channel, string name, key id, string message)
    {
        if (message == "STOP DANCE")
        {
            dance_number = -1;
            llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
        }
        else if (like(message, "PAGE%"))
        {
            showMenu(id, (integer) stristr(message, "PAGE ", TRUE));
        }
        else if (message == "---")
        {
            
        }
        else
        {
            dance_number = (integer) message;
            llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION);
        }
    }
    
    run_time_permissions(integer perms)
    {
        if (perms & PERMISSION_TRIGGER_ANIMATION)
        {
            stopAllDances();
            if (dance_number > -1)
            {
                llStartAnimation(llList2String(dances_list, dance_number));
            }
        }
    }
}

 

  • Like 2
Link to comment
Share on other sites

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