Jump to content

Listener with two counters


testgenord1
 Share

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

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

Recommended Posts

Hi once more!
I'm trying to build a script, that is supposed to listen to two different messages.
The first message ("+") is supposed to add one point to a counter, whereas the second ("-") is to subtract a point.

Both messages are sent in a random sequence,
for example, there could be two consecutive "+", and then one "-", and then three "+", etc. being sent to the listener script,
randomly adding and subtracting points to / from the counter.

Hence, the script must be able to add and subtract points at the same time.
I guess it's not that difficult, but I just can't figure it out.
Do you maybe have an idea?
Any help will be appreciated.
Thank you very much in advance.
Here is the script:

integer i;
default
{
    state_entry()
    {
        llListen(-1008,"",NULL_KEY,"");
    }
    listen(integer channel,string name,key id,string message)
    {
        if(message =="+")
        {
            ++i;
        }
           
        if(message =="-")
        {
            --i;
        }
       
        if(i==6)
        {
            state win;
        }
    }
}
state win
{
    state_entry()
    {
        llSay(0, "\n \n \nCongratulations!\n \nYou've won!\n \n \n");
        llResetScript();
        }
}

 

Link to comment
Share on other sites

Maybe I'm missing something, but doesn't the original script already do what you ask? Rolig's else-if is much cleaner logic-wise, but assuming the message being sent is either "+" or "-", the either code samples will happily add or subtract from the total and if the resulting total would be 6, it moves to the win state.

Are you expecting something different?

  • Like 3
Link to comment
Share on other sites

Thank you very much for your replies.
The win state isn't reached when I use the script.
I can't tell why.
Maybe it's the messenger script and not the listener causing the problem.
I'm posting the messenger script below, maybe it will give you some ideas.
It's a memory game.
The script sends a message when a matching memory game piece is clicked.
This in turn is supposed to trigger the point counter:

// KFM Vocabulary Memory Game Reciever v0.2 by djphil (CC-BY-NC-SA 4.0)
//https://community.secondlife.com/forums/topic/434279-llsetkeyframedmotion-forward-and-back/
list KFMcommand;//changed original script here.

integer canal = -123654789;
integer tempo = 5;
integer echo;
integer count;
integer power;
string lang;
string word;
string trad;
string prim;
vector pos;
rotation rot;

rotation NormRot(rotation Q)
{
    float MagQ = llSqrt(Q.x*Q.x + Q.y*Q.y +Q.z*Q.z + Q.s*Q.s);
    return <Q.x/MagQ, Q.y/MagQ, Q.z/MagQ, Q.s/MagQ>;
}

default
{
    state_entry()
    {
        llSetClickAction(0);
        list buffer = llCSV2List(llGetObjectName());

        if (llGetListLength(buffer) == 2)
        {
            lang = llStringTrim(llList2String(buffer, 0), STRING_TRIM);
            prim = llStringTrim(llList2String(buffer, 1), STRING_TRIM);
        }

        else
        {
            llOwnerSay("Error: Bad prim name detected");
            return;
        }

        buffer = llCSV2List(llGetObjectDesc());

        if (llGetListLength(buffer) == 2)
        {
            word = llStringTrim(llList2String(buffer, 0), STRING_TRIM);
            trad = llStringTrim(llList2String(buffer, 1), STRING_TRIM);
        }
       
        else
        {
            llOwnerSay("Error: Bad prim desc detected");
            return;
        }

        //llSetText("state: ready", <1.0, 1.0, 1.0>, 1.0);
        llSetText("ready", <1.0, 1.0, 1.0>, 1.0);

        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_PHYSICS_SHAPE_TYPE,
            PRIM_PHYSICS_SHAPE_CONVEX
        ]);
    }

    touch_start(integer number)
    {
        llPlaySound(llGetInventoryName(INVENTORY_SOUND,0),1);
        llListenRemove(echo);
        count = 0;

        if (power =! power)
        {
            echo = llListen(canal, prim + "," + lang, NULL_KEY, "");
            llSetTimerEvent(0.1);
        }

        else
        {
            llSetTimerEvent(0.0);
        }

        //llSetText("state: ready", <1.0, 1.0, 1.0>, 1.0);
        llSetText("ready", <1.0, 1.0, 1.0>, 1.0);
    }
   
    listen(integer channel, string name, key id, string message)
    {
        list buffer = llCSV2List(name);

        if (llGetListLength(buffer) == 2)
        {
            name = llList2String(buffer, 0);

            if (name == prim)
            {
                buffer = llCSV2List(message);
               
                if (llGetListLength(buffer) == 3)
                {
                    message = llList2String(buffer, 0);
                    pos = (vector)llList2String(buffer, 1);
                    rot = llList2Rot(buffer, 1);
   
                    if (message == trad)
                    {
                        llListenRemove(echo);
                        power =! power;
                        llShout(canal, message);
                        state move;
                    }
                }   
            }
        }
    }

    timer()
    {
        llSetTimerEvent(1.0);

        llShout(canal, word + "," + (string)llGetPos() + "," + (string)llGetRot());

        if (count > tempo)
        {
            llResetScript();
        }

        llSetText("time left: " + (tempo - count), <1.0, 1.0, 1.0>, 1.0);
        ++count;
    }
}

state move
{
    state_entry()
    {
        llSetClickAction(8);
        llShout(-1008,"+");//	<----------------------------------Here the "plus" message is sent.
        llOwnerSay(llGetScriptName()+" in move state with pos = "+(string)pos);
        rotation spin = NormRot(llEuler2Rot(<90.0, 0.0, 0.0> * DEG_TO_RAD));
        rotation spinz = NormRot(llEuler2Rot(<0.0, 180.0, 0.0> * DEG_TO_RAD));
        KFMcommand = [
            <0.0, 0.0, 1.0> * llGetRot(), ZERO_ROTATION, 0.5,
            pos - llGetPos(), ZERO_ROTATION, 1.0,
            ZERO_VECTOR, spin, 0.5, ZERO_VECTOR, spinz, 0.5, ZERO_VECTOR, spinz, 0.5, 
            ZERO_VECTOR, ZERO_ROTATION, 120.0// hier bleibt es für 120 Sekunden stehen.
            ];
        llSetKeyframedMotion(KFMcommand, [KFM_MODE, KFM_FORWARD]);
        llSleep(5.0);
        llShout(canal, word + "," + (string)llGetPos() + "," + (string)llGetRot());
        llSetKeyframedMotion(KFMcommand, [KFM_MODE, KFM_REVERSE]);
        llShout(canal, trad);
        //llSetText("lang: " + lang + "\nword: " + word + "\ntrad: " + trad, <1.0, 1.0, 1.0>, 1.0);
        llSetTimerEvent(120.0);
    }
    timer()
    {
        llShout(-1008,"-");// <----------------------------------Here the "minus" message is sent.
        llResetScript();
    }
}

 

Link to comment
Share on other sites

I tried your initial script in world with some llOwnerSay lines to announce what it had heard and what the value of I was just before the test to see if it had reached 6. The script works, and at 6 it changed state.

More worrying for me was that a global value declared but not initialised got a default value of 0. I'm not sure how reliable this is, but I do no that not initialising global variables is almost as bad as not initialising automatic variables (which are usually on the stack and so can often get surprisingly sensible values).

ETA having read your subsequent script, I'd suggest two things, change llShout to llRegionSay in case you are exceeding the 100m distance, and put some diagnostic lines in the receiver, as I did, to check it gets a + or a - .

Edited by Profaitchikenz Haiku
  • Like 1
Link to comment
Share on other sites

Ok, I think I see the reason why the receiver never gets to the win state. The sender script only sends a "+" once in the move state entry. It then sets a timer of 120 seconds. It then does some moving and shouting but none of those issue another "+", and none of them change state, so the timer will kick in after 120 seconds, send a "-", and the net result is going to be a 0.

Somewhere in the move state there needs to be a way to return to the default state without the timer event, or else some thing that sends another "+" and resets the timer again to 120 seconds.

Edited by Profaitchikenz Haiku
  • Like 1
Link to comment
Share on other sites

Thank you very much for your time and your help, guys.
I really appreciate this.

34 minutes ago, Profaitchikenz Haiku said:

Ok, I think I see the reason why the receiver never gets to the win state. The sender script only sends a "+" once in the move state entry. It then sets a timer of 120 seconds. It then does some moving and shouting but none of those issue another "+", and none of them change state, so the timer will kick in after 120 seconds, send a "-", and the net result is going to be a 0.

Somewhere in the move state there needs to be a way to return to the default state without the timer event, or else some thing that sends another "+" and resets the timer again to 120 seconds.

This is part of the memory game.
The player has to gain 6 points to win.
He / she only has 120 seconds to achieve this.
After scoring a point, the player has 120 seconds time to find 5 more matches.
After 120 seconds the point is subtracted again (the "-" part), so the player needs to hurry up to finish the game.
I don't think this is where the problem lies, but maybe I'm missing something here.
Thanks for your tip anyway!

 

Link to comment
Share on other sites

seems to me that your issue lies in the data inputs that the script depends on to process

in the script it says this:

if (llGetListLength(buffer) == 3)
                {
                    message = llList2String(buffer, 0);
                    pos = (vector)llList2String(buffer, 1);
                    rot = llList2Rot(buffer, 1);

why would pos and rot be using the same data input ? when buffer has a 3rd element which is not used

and without knowing what the data inputs are then is difficult to pinpoint other problems which result because of invalid data

edit add. Best to start sticking in lots of llSay and dump var values to chat. Checking them against the input data source

 

 

Edited by Mollymews
  • Like 1
Link to comment
Share on other sites

This thread has taken me back to my first days in SL when I would look through somebody else's script and try to fathom out how to make it do what I wanted. The sheer complexity of some of them gave me major headaches. After a couple of months I found it was easier to write my own scripts starting with small test harnesses to look at one part of the problem at a time, and as each small part was perfected I would begin integrating them together.

  • Like 1
Link to comment
Share on other sites

I suspect that's how most of us started scripting, Prof.  Each of us develops an idiosyncratic style that makes sense to us but would probably not be wise for someone else to copy. The only way that I can be sure that I understand how a script of any complexity is meant to work is by writing it myself.  As much as I learned from Void and Strife and the other old masters in their day, I would never just grab one of their scripts and run with it.   And yes, I always write anything complicated in modular style, testing small parts separately and then gluing the mess together as a final step.

Link to comment
Share on other sites

  • 2 weeks later...

Hi again.
I've come up with a version that seems to work.
The issue seems to have been partly caused by lag on the SIM, which had to be restarted.
There might be some flaws left in it.
Particularly the last part containing the "llOwnerSay("-");"
sometimes caused some problems.

I'm posting it below.
You're welcome to comment.
Thank you very much for your help!

// KFM Vocabulary Memory Game Reciever v0.2 by djphil (CC-BY-NC-SA 4.0)
//https://community.secondlife.com/forums/topic/434279-llsetkeyframedmotion-forward-and-back/
list KFMcommand;//changed original script here.
integer canal = -123654789;
integer tempo = 5;
integer echo;
integer count;
integer power;
string lang;
string word;
string trad;
string prim;
vector pos;
rotation rot;
rotation NormRot(rotation Q)
{
    float MagQ = llSqrt(Q.x*Q.x + Q.y*Q.y +Q.z*Q.z + Q.s*Q.s);
    return <Q.x/MagQ, Q.y/MagQ, Q.z/MagQ, Q.s/MagQ>;
}
default
{
    state_entry()
    {
        llSetClickAction(0);
        list buffer = llCSV2List(llGetObjectName());
        if (llGetListLength(buffer) == 2)
        {
            lang = llStringTrim(llList2String(buffer, 0), STRING_TRIM);
            prim = llStringTrim(llList2String(buffer, 1), STRING_TRIM);
        }
        else
        {
            llOwnerSay("Error: Bad prim name detected");
            return;
        }
        buffer = llCSV2List(llGetObjectDesc());
        if (llGetListLength(buffer) == 2)
        {
            word = llStringTrim(llList2String(buffer, 0), STRING_TRIM);
            trad = llStringTrim(llList2String(buffer, 1), STRING_TRIM);
        }
        else
        {
            llOwnerSay("Error: Bad prim desc detected");
            return;
        }
        //llSetText("state: ready", <1.0, 1.0, 1.0>, 1.0);
        llSetText("ready", <1.0, 1.0, 1.0>, 1.0);
        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_PHYSICS_SHAPE_TYPE,
            PRIM_PHYSICS_SHAPE_CONVEX
        ]);
    }

    touch_start(integer number)
    {
        llPlaySound(llGetInventoryName(INVENTORY_SOUND,0),1);
        llListenRemove(echo);
        count = 0;
        if (power =! power)
        {
            echo = llListen(canal, prim + "," + lang, NULL_KEY, "");
            llSetTimerEvent(0.1);
        }
        else
        {
            llSetTimerEvent(0.0);
        }
        //llSetText("state: ready", <1.0, 1.0, 1.0>, 1.0);
        llSetText("ready", <1.0, 1.0, 1.0>, 1.0);
    }
   
    listen(integer channel, string name, key id, string message)
    {
        list buffer = llCSV2List(name);

        if (llGetListLength(buffer) == 2)
        {
            name = llList2String(buffer, 0);
            if (name == prim)
            {
                buffer = llCSV2List(message);
                if (llGetListLength(buffer) == 3)
                {
                    message = llList2String(buffer, 0);
                    pos = (vector)llList2String(buffer, 1);//changed original script here.
                    rot = llList2Rot(buffer, 1);
                    if (message == trad)
                    {
                        llListenRemove(echo);
                        power =! power;
                        llShout(canal, message);
                        state move;
                    }
                }   
            }
        }
    }
    timer()
    {
        llSetTimerEvent(1.0);
        llShout(canal, word + "," + (string)llGetPos() + "," + (string)llGetRot());
        if (count > tempo)
        {
            llResetScript();
        }
        llSetText("time left: " + (tempo - count), <1.0, 1.0, 1.0>, 1.0);
        ++count;
    }
}

state move//changed original script here.
{
    state_entry()
    {
        llShout(-1008,"+");
        llOwnerSay("+");
        llSetTimerEvent(120.0);
        llListen(canal,"",NULL_KEY,"");
        llOwnerSay(llGetScriptName()+" in move state with pos = "+(string)pos);
        rotation spin = NormRot(llEuler2Rot(<90.0, 0.0, 0.0> * DEG_TO_RAD));
        rotation spinz = NormRot(llEuler2Rot(<0.0, 180.0, 0.0>* DEG_TO_RAD));
        KFMcommand = [
            <0.0, 0.0, 1.0> * llGetRot(), ZERO_ROTATION, 0.5,
            pos - llGetPos(), ZERO_ROTATION, 1.0,
            ZERO_VECTOR, spin, 0.5,
            ZERO_VECTOR, spinz, 0.5,
            ZERO_VECTOR, spinz, 0.5,           
            ZERO_VECTOR, ZERO_ROTATION, 5.0// hier bleibt es für 5 Sekunden stehen.
            ];
        llSetKeyframedMotion(KFMcommand, [KFM_MODE, KFM_FORWARD]);
        llSleep(5.0);   
    }
    listen(integer channel, string name, key id, string message)
    {
        if(message=="reset")
        {
        llOwnerSay("reset");
        llShout(canal, word + "," + (string)llGetPos() + "," + (string)llGetRot());
        llSetKeyframedMotion(KFMcommand, [KFM_MODE, KFM_REVERSE]);
        llShout(canal, trad);
        llSetText("lang: " + lang + "\nword: " + word + "\ntrad: " + trad, <1.0, 1.0, 1.0>, 1.0);
        llResetScript();
        }
    }
    timer()
    {
        llOwnerSay("Time's up.");
        llShout(-1008,"-");
        llOwnerSay("-");
        llShout(canal, word + "," + (string)llGetPos() + "," + (string)llGetRot());
        llSetKeyframedMotion(KFMcommand, [KFM_MODE, KFM_REVERSE]);
        llShout(canal, trad);
        llSetText("lang: " + lang + "\nword: " + word + "\ntrad: " + trad, <1.0, 1.0, 1.0>, 1.0);
        llResetScript();
    }
}

the counter script:
 

integer ListenHandle;
integer i;
default
{
    state_entry()
    {
        integer ListenHandle = llListen(-1008,"",NULL_KEY,"");
    }
    listen(integer channel,string name,key id,string message)
    {
        if(message =="+")
        {
            ++i;
        }
        if(message =="-")
        {
            --i;
        }
        if(i==6)
        {
            llListenRemove(ListenHandle);
            state win;
        }
    }
}
state win
{
    state_entry()
    {
        llShout(0, "\n \n \nCongratulations!\n \nYou've won!\n \n \nDies ist deine Medaille.\n \nKlicke auf sie, um sie zu behalten.");
        llShout(-123654789,"reset");
        llRezAtRoot(llGetInventoryName(INVENTORY_OBJECT, 0), llGetPos() + <0.0,-5.0,0.0>,ZERO_VECTOR,llEuler2Rot(<90.0,0.0,180.0> * DEG_TO_RAD)*llGetRot(),0);
        llPlaySound("ed124764-705d-d497-167a-182cd9fa2e6c ",1.0);
        llResetScript();
     }
}

 

Link to comment
Share on other sites

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