testgenord1 Posted January 25, 2020 Share Posted January 25, 2020 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 More sharing options...
Rolig Loon Posted January 25, 2020 Share Posted January 25, 2020 You really mean listen(integer channel,string name,key id,string message) { if(message =="+") { ++i; } else if(message =="-") // Here's the trick. { --i; } if(i==6) { state win; } } 😎 1 Link to comment Share on other sites More sharing options...
Fenix Eldritch Posted January 25, 2020 Share Posted January 25, 2020 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? 3 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted January 25, 2020 Share Posted January 25, 2020 It would help to initialise i to 0 before starting. 1 Link to comment Share on other sites More sharing options...
testgenord1 Posted January 25, 2020 Author Share Posted January 25, 2020 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 More sharing options...
Profaitchikenz Haiku Posted January 25, 2020 Share Posted January 25, 2020 (edited) 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 January 25, 2020 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted January 25, 2020 Share Posted January 25, 2020 (edited) 56 minutes ago, Profaitchikenz Haiku said: It would help to initialise i to 0 before starting. All variables are always initialized to zero-values in LSL. You're right that in some languages, for example C, this isn't case. LSL is a safe language though. Edited January 25, 2020 by Wulfie Reanimator 1 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted January 25, 2020 Share Posted January 25, 2020 1 minute ago, Wulfie Reanimator said: But LSL is a safe language. Dam, that's taken half the fun out of scripting. 1 2 Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted January 25, 2020 Share Posted January 25, 2020 (edited) 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 January 25, 2020 by Profaitchikenz Haiku 1 Link to comment Share on other sites More sharing options...
testgenord1 Posted January 25, 2020 Author Share Posted January 25, 2020 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 More sharing options...
Mollymews Posted January 26, 2020 Share Posted January 26, 2020 (edited) 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 January 26, 2020 by Mollymews 1 Link to comment Share on other sites More sharing options...
testgenord1 Posted January 26, 2020 Author Share Posted January 26, 2020 Hi again! Thank you very much for your help, again. It worked better today without actually changing the script, but again not all the time. I'll do more experiments with it and write back to you next week. Thanks again! Link to comment Share on other sites More sharing options...
Profaitchikenz Haiku Posted January 26, 2020 Share Posted January 26, 2020 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. 1 Link to comment Share on other sites More sharing options...
Rolig Loon Posted January 26, 2020 Share Posted January 26, 2020 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 More sharing options...
testgenord1 Posted January 26, 2020 Author Share Posted January 26, 2020 (edited) I'm still not quite there yet. I'll post more next week. Thanks everyone! Edited January 26, 2020 by testgenord1 Link to comment Share on other sites More sharing options...
testgenord1 Posted February 3, 2020 Author Share Posted February 3, 2020 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 More sharing options...
Recommended Posts
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