Jump to content

testgenord1

Resident
  • Posts

    146
  • Joined

  • Last visited

Everything posted by testgenord1

  1. Hi! I've written a script that starts on touch_start. After starting the script, the touch_start event is supposed to be deactivated for some time, so that nobody can restart the script as long as the process has not been finished: integer on; touch_start (integer num) { if(!on) { on = TRUE; *do something* } else { return; } This seems to work (the only thing I'm not quite sure about is the "else" part with "return". Couldn't you just leave the "else" part out?) Now my main question: I've tried a similar version, which does NOT work, and I don't really understand the difference: integer on; default { state_entry() { on = FALSE; touch_start (integer num) { if(on = FALSE) { on = TRUE; *do something* } else { return; } } } } The problem apparently is that "!on" and "on = FALSE" don't seem to be the same thing. Could one of you explain the difference between "!on" and "on = FALSE" to me? (Besides: Is it necessary to declare the integer "on" as FALSE at the beginning? Is integer "on" not FALSE by default before it is turned TRUE?) Thank you very much in advance!
  2. Thanks a million, Mollymews! This script works really beautifully. I couldn't have done it without your help. I'm posting the updated quiz below. Maybe someone has some use for it later. I've probably still left some flaws in the script, so everybody still feel free to comment further. Again, thank you so much for your help!🙂 list lpoints; list lnames; integer length; integer ListenHandle; integer inumber = 1; //number of expected correct answers string sname; default { state_entry() { ListenHandle = llListen(-1121,"",NULL_KEY,""); } listen(integer channel,string name,key id,string message) { llSensorRepeat("","",AGENT_BY_LEGACY_NAME,10.0,PI,10.0); lpoints = lpoints + [message]; // The key of a player with a correct answer is put on the list. lnames = [message]; // The key of the player length = llGetListLength(lpoints); string search = message; integer count = length - llGetListLength(llParseString2List(llDumpList2String(lpoints, " "), [" ", search], [])); if(count == inumber) { sname = llKey2Name(search); llRegionSayTo(search,0,"\n \n \nCongratulations!\n \n" + sname + " has won the game!\n \n \n \n \n"); lpoints = llParseString2List(llDumpList2String(lpoints, " "), [" ", search], []); } } no_sensor() { //llOwnerSay("No avatar around any more."); llResetScript(); } }
  3. Thank you very much for your quick reply, Rolig Loon! I've learned a lot from it. "K" produced the value 0 for me when I checked. But it's true, there probably is a connection between removing the last element of the list and the complete removal loop. The script certainly isn't the best. In case you or anyone else have more ideas, you're welcome to comment further. Thank you very much for your help, once again!
  4. Hi again! I've got a script counting correct replies from players in a quiz. With each correct reply the name of the player is shouted to a counter (the script below). The counter puts the names of the players on a list. When a player has reached a certain number of correct replies (here 3), he / she has won. The script seems to work so far. The only two things I could not figure out is: 1. When I want to be shown all entries on the list by llList2String, only one entry is shown, but not the others (llGetListLength shows more entries, though.). 2. I try to delete the name of the winning player in the end. But instead all player names are deleted. Do you see how to change these two things? Any help will be appreciated. // The main function was taken from "count occurrences in list; by Dora Gustafson, Studio Dora// v1.1 inline code" list lpoints; list lnames; integer ListenHandle; default { state_entry() { integer ListenHandle = llListen(-1121,"",NULL_KEY,""); } listen(integer channel,string name,key id,string message) { if(message) // The message is the name of the player. { lpoints = lpoints + [message]; // The name of a player with a correct answer is put on the list. lnames = [message]; // The name of the player integer i = 0; integer j = 0; integer k = llListFindList( lpoints, lnames); // The name of the player is searched for on the list. integer m = llGetListLength( lpoints ); while ( k >= 0 && i < m ) { i += k+1; k = llListFindList( llList2List( lpoints, i, -1), lnames); ++j; if(j == 3) // If the player has given 3 correct replies ... { string swinner = llList2String(lnames,0); llOwnerSay(swinner + " has won!"); llOwnerSay("list length: " + m); // <-- This shows the number of all player names on the list. integer a; for(a=0;a<m;++a) { llOwnerSay(llList2String(lpoints,a)); // <-- This only shows one player name, but not the others. integer index = llListFindList(lpoints,swinner); lpoints = llDeleteSubList(lpoints,index,index); // <-- This deletes all player names on the list. llOwnerSay("new list length: " + llGetListLength(lpoints)); } } } } } }
  5. Thank you so much for your quick reply and working through my script. Your suggestion seems to have done the trick. The list showed up empty after several clicks. So thank you very much for your help, again!🙂 edit: In order to show you what I wanted to do with the script, I'm posting a slightly different version of the script below. It teleports an avatar to a different prim in the linkset through saying the name of that prim. It seems to work. I hope it stays that way. (In that version, the vector does not need to be taken off the list. Besides, It is made for OpenSim and so there is no experince permission for the teleporter, which would have to be added in SL.) I'm posting the script below. The script certainly has more room for improvement, and so feel free to comment further. Thank you very much for your ideas, once again. integer primnum; list lprimpos; string region; key player; integer imessage; default { state_entry() { llSetClickAction(CLICK_ACTION_TOUCH); } touch_start(integer num) { player = llDetectedKey(0); llSetClickAction(8); llListen(0,"","",""); llSetTimerEvent(10.0); llRegionSayTo(player,0,"Please write the name of the next station into the chat and press 'Enter'."); } listen(integer channel, string name, key id, string message) { region = llGetRegionName(); primnum = llGetNumberOfPrims(); integer i; for (i=1; i <= primnum; ++i) //link numbering in linksets starts with 1 { lprimpos = llGetLinkPrimitiveParams(i,[PRIM_NAME,PRIM_POSITION]); lprimpos = llListSort(lprimpos, 2, TRUE); // sort strided list by ascending name (name used because it comes before vector [DetName,vpos]); TRUE means ascending order. imessage = llListFindList(lprimpos,message); if(imessage != -1) { vector pos = llList2Vector(lprimpos,imessage+1); //llOwnerSay((string)pos); osTeleportAgent(id,region,pos,<0.0,0.0,0.0>); llResetScript(); } } } timer() { llRegionSayTo(player,0,"Click to start again."); llResetScript(); } }
  6. part 2: (I hope I'm not annoying you too much.) In order to reduce script count, I'm using a slight variation using a linkset and detecting the parameters of the child prims instead of the sensor. What I would like to do now is the following: The prims (i.e. their location vectors) of the respective linkset can be individually used by touch_start as long as they are on the list (lprimpos). However, each prim is only supposed to be used once. This means, once it has been touched, it should to be taken off the list. I tried to do that but got stuck, when it comes to the list. The vectors on the list are being correctly named by (llList2String(lprimpos,n). But I cannot take them off the list. (When I check by touching if a vector is on the list, the result is negative (although it was named right before as being on the list by llList2String).) Maybe one of you can see why deleting the vectors from the list is not possible? Thank you very much in advance! vector vprimpos; list lprimpos; integer primnum; //key id; //string region; vector vtouchedprim; default { state_entry() { //region = llGetRegionName(); primnum = llGetNumberOfPrims(); integer i; for (i=1; i <= primnum; i++) //link numbering in linksets starts with 1 { lprimpos=llGetLinkPrimitiveParams(i,[PRIM_POSITION]); integer n; for(n=0; n<=primnum; n++) llOwnerSay(llList2String(lprimpos,n)); //check what elements are on the list. } } touch_start(integer num) { //id = llDetectedKey(0); integer itouchedprim = llDetectedLinkNumber(0); llOwnerSay("link number touched: " + (string)itouchedprim); //check which linked prim has been touched. vtouchedprim = llList2Vector(llGetLinkPrimitiveParams(itouchedprim,[PRIM_POSITION]),0); llOwnerSay("position of touched: " + (string)vtouchedprim); //check position vector of the prim touched. { integer idxprimpos = llListFindList(lprimpos, vtouchedprim); llOwnerSay((string)idxprimpos); //check whether vector of prim touched is on the list. if(llListFindList(lprimpos, vtouchedprim) != -1) //if vector is on the list ... lprimpos = llDeleteSubList(lprimpos, idxprimpos, idxprimpos); //delete vector from the list. integer m; for(m=0; m<=primnum; m++) llOwnerSay("new list: " + llList2String(lprimpos,m)); //check elements on the new list. } } }
  7. Thank you so much for your help! This seems to have done the trick. I think there was a very little typo, which is, the line if(llToLower(llGetSubString(llDetectedName(i)), 0, 2) == "voc") lnames = lnames + llDetectedName(i); //only object names starting with "voc" are put on the list. probably has to be if(llToLower(llGetSubString(llDetectedName(i), 0, 2)) == "voc") { lnames = lnames + llDetectedName(i); //only object names starting with "voc" are put on the list. and likewise also in the second script? The scripts are awesome. Thank you so much for your support!
  8. Thank you very much for your quick reply. After casting the list into a string using llList2String, I was able to find the index of the first word starting with "voc" (, which was 0), as you described. However, some of my problems still remain: - I could only find one word starting with "voc" in the resulting string, but not the other ones. - What do I do with the index I've found so I can eventually use the object's complete name from the list? The problem is further complicated by the fact that the words are on a list and not in a string, at first.
  9. Hi! I'm trying to write a script in which a sensor puts objects' names on a list. However, I only want to use objects starting with a particular beginning, e.g. "voc" (for "vocabulary"). These objects are supposed to be used for other purposes. This means either: - only objects with such a beginning are put on the list or - only objects with such a beginning on the list are used. This is the step I haven't been able to achieve. (I tried llGetSubString, but unsuccessfully.) How can I filter a list in such a way that only objects beginning with "voc" are used in the script later on? Here is my script so far (it works so far): list lnames; default { state_entry() { llSensor("","",PASSIVE,96.0,PI); } sensor(integer num) { integer i; for(i = 0; i < num; ++i) lnames = lnames + llDetectedName(i); //all object names found by the sensor are put on the list. integer j; for(j = 0; j < num; ++j) llSay(0,llList2String(lnames,j)); //the object names on the list are used. } } Thank you very much in advance!
  10. Hi again! Thank you very much for your suggestions! Somebody on OpenSim wrote a completely new script for me, solving the problem. I'm posting it below. Since it is for Opensim, it does not contain the experience permission, which would have to be added for SL. I might add your suggestions, for example the swimming animations, to the script later. Thank you very much, once again! // Diving Collision v0.1 by djphil (CC-BY-NC-SA 4.0) string jumpto = "jumping point"; float timeout = 30.0; float range = 32.0; list animations = [ "backflip", "jump", "sit" ]; string animation; string region; key user_uuid; integer canal; integer echo; default { state_entry() { llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0, PRIM_PHANTOM, FALSE ]); region = llGetRegionName(); integer number = llGetInventoryNumber(INVENTORY_ANIMATION); if (number <= 0) {llOwnerSay("Animation(s) missing ..."); return;} integer length; integer i; do { animation = llGetInventoryName(INVENTORY_ANIMATION, i); length = llStringLength(animation); if (length > 0 && length < 24) animations += llGetInventoryName(INVENTORY_ANIMATION, i); else llOwnerSay("Invalid animation name " + animation); } while (++i < number); length = llGetListLength(animations); if (llGetListLength(animations) < 13) state ready; else llOwnerSay("Invalid animation number ..."); } } state ready { collision_start(integer n) { user_uuid = llDetectedKey(0); state diving; } } state diving { state_entry() { canal = -1 -(integer)("0x" + llGetSubString( (string)user_uuid, -7, -1)); echo = llListen(canal, "", user_uuid, ""); llDialog(user_uuid, "What jump do you want?", animations, canal); llSetTimerEvent(timeout); } listen(integer channel, string name, key id, string message) { llSetTimerEvent(0.0); llListenRemove(echo); animation = message; llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 0.0, PRIM_PHANTOM, TRUE ]); osAvatarPlayAnimation(user_uuid, animation); llSleep(1.0); llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0, PRIM_PHANTOM, FALSE ]); //llSleep(1.0); llPlaySound(llGetInventoryName(INVENTORY_SOUND, 0), 1.0); llSensor(jumpto, NULL_KEY, PASSIVE, range, PI); } sensor(integer n) { integer i; for (i = 0; i < n; i++) { vector det_pos = llDetectedPos(i); rotation det_rot = llDetectedRot(i); vector lookat = llRot2Euler(det_rot) * RAD_TO_DEG; //llSleep(5.0); osTeleportAgent(user_uuid, region, det_pos, lookat); osAvatarStopAnimation(user_uuid, animation); user_uuid = NULL_KEY; state ready; } } no_sensor() { llSetTimerEvent(0.0); llListenRemove(echo); osAvatarStopAnimation(user_uuid, animation); llOwnerSay(jumpto + " no found ..."); state ready; } collision_start(integer n) { integer i; for (i = 0; i < n; i++) { key uuid = llDetectedKey(i); if (uuid != user_uuid) { llSay(PUBLIC_CHANNEL, "Sorry " + llKey2Name(uuid) + ", the diving board is currently used by " + llKey2Name(user_uuid)); } } } timer() { llSetTimerEvent(0.0); llListenRemove(echo); state ready; } }
  11. Thank you very much for your quick reply. I'm using the script on Opensim. On Opensim, you can teleport non-owner avatars without experience events. Strangely, in this case however, the owner is teleported in addition to the colliding avatar. (Both are teleported.) This is why I thought a list might help, but it causes the same problem. I guess this might be more an Opensim problem then. Thank you very much for trying to help, though!
  12. Hi! I've got a script that makes an avatar jump from a jumping tower into a swimming poo. It triggers a jumping animation through a collision_start event when stepping on the tower. After the jump the avatar having done the jump is teleported back onto the tower. This already works. What I want to do is the following: As long as the avatar is using the tower, no other avatar should be able to use it. This is why I put the jumping avatar on a list allowing only the one avatar on the list to use the script. Here is the problem: When that particular avatar is teleported back onto the tower, a second avatar near the tower is also teleported onto the tower without having triggered the collision_start event, which should not happen. I don't understand why. Do you maybe see where the problem is? Thank you very much in advance! Here is the script: string gStrAnim; //used for the animations string gStrGesture; //used for the animations key av; string region; list jumper; // List on which the colliding avatar is put. Only 1 avatar is allowed on the list. integer ljumper; // Length of the list. Should be one. integer avposlist; // Index of the avatar on the list. list gLstBtnGesture = // animation buttons for dialog [ "back flip", "dive high", "dive low", "flip slow", "jump", "spin" ]; list gLstGestures = // animations in the inventory triggered by the buttons [ "back flip", "dive high", "dive low", "flip slow", "jump", "spin" ]; gFnDlgGestures() { llDialog(av, "What jump do you want?", gLstBtnGesture, -897); // dialog menu for triggering the animations } default { state_entry() { llSetPrimitiveParams([ PRIM_COLOR, ALL_SIDES,<1.0, 1.0, 1.0>, 1,PRIM_PHANTOM,FALSE]); gStrAnim=llGetInventoryName(INVENTORY_ANIMATION,0); // animations } collision_start(integer num) { llSetTimerEvent(1.0); av = llDetectedKey(0); llListen(-897,"",NULL_KEY,""); gStrAnim=llGetInventoryName(INVENTORY_ANIMATION,0); // animations ljumper = llGetListLength(jumper); // length of the list containing the avatar; should be 0 here. llOwnerSay("number of avs on list = " + (string)ljumper); if(ljumper < 1) // If no avatar is on the list yet ... { jumper = [av] + jumper; // avatar is put on the list. ljumper = llGetListLength(jumper); // length of the list containing the avatar; should be 1 now. llOwnerSay("putting " + (string)av + "on the list"); llOwnerSay("number of avs on list = " + (string)ljumper); avposlist = llListFindList(jumper,av); if(avposlist != -1) // if avatar is found on the list ... { llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); // ... request permission to animate. llOwnerSay("requesting permission from " + av); } } else { llOwnerSay("list is full"); // If 1 avatar is already on the list, no second avatar is accepted. } } run_time_permissions(integer perm) { if(perm & PERMISSION_TRIGGER_ANIMATION) { gFnDlgGestures(); // dialog menu for animations is started. } } listen(integer channel, string name, key id, string message) { if (llListFindList(gLstBtnGesture, [message]) != -1) // animation is started through the menu. { region = llGetRegionName(); gStrGesture = llList2String(gLstGestures, llListFindList(gLstBtnGesture, [message])); llStartAnimation(gStrGesture); // animation is performed. llSleep(0.5); llSetPrimitiveParams([ PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 0,PRIM_PHANTOM,TRUE]); llSleep(1.5); llPlaySound(llGetInventoryName(INVENTORY_SOUND,0),1); llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES,<1.0, 1.0, 1.0>, 1,PRIM_PHANTOM,FALSE]); llSleep(5.0); llSensor ("jumping point", NULL_KEY, PASSIVE ,96.0,PI); // After performing the animation, the script searches for the jumping tower. } } sensor(integer number) { vector det_pos = llDetectedPos(0); avposlist = llListFindList(jumper,av); if(avposlist != -1) // If the avatar is on the list ... llOwnerSay(av + "is on the list and teleported"); { llTeleportAgent(av,"", det_pos, det_pos); // ... the avatar is teleported back onto the jumping point. llResetScript(); } } }
  13. Maths has never been my greatest strength and so I have to admit I haven't understood every detail of how the process works, I'll have a look at the exact details of the process later. But I certainly got the point of what you are saying. I'll just remember to go through such lists from end to start. So, thank you very much for your clear and detailed explanation! 🙂
  14. I think I finally figured it out the hard way: It leads to an endless loop? At least that's what happened to me for 30 minutes before I eventually remembered your clue. So thanks for that, too! 🙂
  15. Hi again! Thank you very much for your ideas, Kardargo. I really appreciate this. Aftere some more failed attempts, I ended up using a different method again. It seems to work so far. I've integrated parts from another script Rolig Loon helped me with: So thank you very much, once again, Rolig Loon! I'm posting the script below. There might still be a lot of room for improvements, so feel free to comment further. string Destination = "your_region"; vector LandingPoint = <77,154,22>; // X,Y,Z landing point for avatar to arrive at vector LookAt = <1,1,1>; // which way they look at when arriving// list avatarsInRegion; integer numOfAvatars; key id; string name; list newkeys; integer listpos; integer arrivaltime; integer seconds; integer time = 180; default { state_entry() { avatarsInRegion = llGetAgentList(AGENT_LIST_PARCEL, []); numOfAvatars = llGetListLength(avatarsInRegion); llVolumeDetect(TRUE); } collision_start(integer n) { llSetTimerEvent(1.0); id = llDetectedKey(0); name = llKey2Name(id); llRegionSayTo(id,0, "Welcome " + name + "!\n \nYou have 3 minutest time.\n \nThen you will be teleported back."); if(llListFindList(newkeys,id) == -1) { arrivaltime = llGetUnixTime(); integer i; for(i=0; i < numOfAvatars; ++i); { //llShout(0,"key: " + (string)id); newkeys += [arrivaltime,id]; // add Unix Time and key to the list; Unix Time first position, key second position newkeys = llListSort(newkeys, 2, TRUE); // sort strided list by ascending arrivaltime (arrivaltime used because it comes before key [arrivaltime,id]); TRUE means ascending order listpos = llListFindList(newkeys,id); // search for key in list if(listpos > 7) // if the key is in the 8th onwards position, its agent will be teleported; this means user 5 onwards, because position 8 is in stride 5 (= user 5) (0,1; 2,3; 4,5; 6,7; 8,9 ...) { llRegionSayTo(id,0,"Sorry, the task is full.\n \n \nYou are teleported back."); llTeleportAgent(id,"",LandingPoint,LookAt); newkeys = llDeleteSubList(newkeys,4,5); // ... the 3rd avatar arriving (3rd stride) is teleported and removed from the Visitor list } } } } timer() { ++seconds; if(seconds > time) { integer k; for (k=((newkeys !=[])-1);k>=0;--k) //Look through all the saved visitor times { // For each one ... if((llGetUnixTime() - llList2Integer(newkeys, k)) > time) // If it was more than 180 seconds ago ... { llRegionSayTo(id,0, "Sorry, but your time is up.\n \n You will be teleported back in 3 seconds.\n \nBye!"); if(seconds = 3) { llInstantMessage(id, "Teleporting you to : "+ Destination); llTeleportAgent(id,"",LandingPoint,LookAt); //llSay(0,"current keys on list: "+llList2String(newkeys, k+1)); //Check AV key //llSay(0,"current arrivaltimes on list: "+llList2String(newkeys, k)); //Check AV arrivaltime newkeys = llDeleteSubList(newkeys, k+1, k+1); // Remove Av from visitor list newkeys = llDeleteSubList(newkeys, k, k); // Remove Av's arrivaltime, too //llSay(0,"reset keys on list: "+llList2String(newkeys, k+1)); //Check if Av was removed (no key returned) //llSay(0,"reset arrivaltimes on list: "+llList2String(newkeys, k)); //Check if arrivaltime was removed (no integer returned) } } } } } touch_start(integer num_detected) { id=llDetectedKey(0); integer j; for(j = 0; j < numOfAvatars; ++j); { j = llListFindList(newkeys,id); llInstantMessage(id, "Teleporting you to : "+ Destination); llTeleportAgent(id,"",LandingPoint,LookAt); //llSay(0,"keys: "+llList2String(newkeys,j)); // Say key of agent touching //llSay(0,"times: "+llList2String(newkeys,j-1)); // Say integer arrivaltime of agent touching newkeys = llDeleteSubList(newkeys,j,j); // Remove Av from visitor list newkeys = llDeleteSubList(newkeys,j-1,j-1); // Remove Av's arrivaltime, too //llSay(0,"neue keys: "+llList2String(newkeys,j)); //Check if Av was removed (no key returned) //llSay(0,"neue times: "+llList2String(newkeys,j-1)); //Check if arrivaltime was removed (no integer returned) } } }
  16. Thank you very much for your quick and helpful reply. I don't know why, but I'm still failing at this. I just can't figure it out. I'm posting it below. Maybe I cannot see the forest for the trees. Can you find the mistake? string Destination = "Sandbox"; vector LandingPoint = <141,108,103>; // X,Y,Z landing point for avatar to arrive at vector LookAt = <1,1,1>; // which way they look at when arriving// list avatarsInRegion; integer numOfAvatars; key kbouncer; list lbouncerpos; vector vbouncerpos; integer seconds; key id; list lavpos; vector vavpos; float fvectordistance; default { state_entry() { kbouncer = llGetKey(); vbouncerpos = llGetPos(); llSetTimerEvent(1.0); } timer() { ++seconds; if(seconds % 5 == 0) { integer i; for(i=0; i < numOfAvatars; ++i); { avatarsInRegion = llGetAgentList(AGENT_LIST_PARCEL, []); numOfAvatars = llGetListLength(avatarsInRegion); id = llList2Key(avatarsInRegion,i); lavpos = llGetObjectDetails(id,[OBJECT_POS]); vavpos = llList2Vector(lavpos,0); fvectordistance = llVecDist(vbouncerpos, vavpos); //llOwnerSay(,(string)fvectordistance); if (numOfAvatars >1) { if(fvectordistance < 10) { llRegionSayTo(id,0,"Sorry, the task is full.\n \n \nTeleporting you back ..."); osTeleportAgent(id,Destination,LandingPoint,LookAt); avatarsInRegion = llDeleteSubList(avatarsInRegion,i,i); // Remove the person from the Visitor list } } } } if(seconds % 180 == 0) { avatarsInRegion = llDeleteSubList(avatarsInRegion,0,10); // Remove the person from the Visitor list } } } edit: With this setting, only one avatar is teleported, and only at his / her first encounter with the prim, but not at the second encounter any more.
  17. Hi again! Thanks to all of your help, I've managed to roughly get the script that I wanted. There is basically only one problem I haven't been able to solve, and for you guys it's probably a very basic one: In this version, 2 avatars can stay near that scripted prim at the same time. The third avatar approaching will be teleported. (Btw, I'm using the teleporter in school to make sure the students can only go to each task in limited numbers, so they won't distract each other.) Now my problem: With this setting, ONLY the third avatar will be teleported. Should a fourth avatar arrive at the same time, he / she would only be teleported after having been in the 3rd slot in the next timer interval. That avatar would remain in that building throughout the timer interval. I guess I would have to use a variable for id = llList2Key(avatarsInRegion, 2); instead of "2", so that ALL AVATARS starting with the third on the list, will be teleported. I tried the following, but it hasn't worked: integer i; for(i=0; i < numOfAvatars; ++i) { id = llList2Key(avatarsInRegion, i); } I have to admit, I still haven't quite understood how the "++i" works. I thought it meant the variable will go through all elements / keys on the list consecutively. Instead, what it does now is, it only takes the very last key on the list (I guess in the place of "numOfAvatars") but does not take the other keys on the list. Maybe you can also help me with this thing? A short explanation of how "++i" works I would also be thankful for, because I just couldn't quite understand it from the online materials. Thank you very much in advance! Here is the script: vector LandingPoint = <77,154,22>; // X,Y,Z landing point for avatar to arrive at vector LookAt = <1,1,1>; // which way they look at when arriving// list avatarsInRegion; integer numOfAvatars; key kbouncer; list lbouncerpos; vector vbouncerpos; integer seconds; key id; list lavpos; vector vavpos; float fvectordistance; default { state_entry() { kbouncer = llGetKey(); vbouncerpos = llGetPos(); llSetTimerEvent(1.0); } timer() { ++seconds; if(seconds % 10 == 0) { avatarsInRegion = llGetAgentList(AGENT_LIST_PARCEL, []); numOfAvatars = llGetListLength(avatarsInRegion); id = llList2Key(avatarsInRegion,2); lavpos = llGetObjectDetails(id,[OBJECT_POS]); vavpos = llList2Vector(lavpos,0); fvectordistance = llVecDist(vbouncerpos, vavpos); //llOwnerSay(,(string)fvectordistance); if (numOfAvatars >1) { if(fvectordistance < 10) { llRegionSayTo(id,0,"Sorry, the task is full.\n \n \nTeleporting you back ..."); llTeleportAgent(id,"",LandingPoint,LookAt); avatarsInRegion = llDeleteSubList(avatarsInRegion,2,2); // Remove the person from the Visitor list } } } if(seconds % 180 == 0) { avatarsInRegion = llDeleteSubList(avatarsInRegion,0,10); // Remove the person from the Visitor list } } }
  18. Wow, thank you so much for your quick and detailed reply. I'll check that out tomorrow. It's already very late over here. 🙂 Thank you very much, once again, Rolig Loon, you're amazing.
  19. Hi! I would like to limit the access to a building to a certain number of avatars, let's say 10 at the same time. Should an 11th avatar try to access the building, he / she should be teleported back to a central starting point. In order to do that, the avatars have to be counted and put on a list. Has a certain number of avatars been put on the list, the list should be closed. Any avatar not on the list should be teleported back. The main problem seems to be to exclusively pick the avatars which are not on the list to teleport, as opposed to the avatars that are. Maybe one of you can help me out? Here is the script: Thank you very much in advance! vector LandingPoint = <77,154,22>; // X,Y,Z landing point for avatar to arrive at vector LookAt = <1,1,1>; // which way they look at when arriving// key id; float Range=20.0; float Rate=10.0; integer PositionInList; list visitors; default { state_entry() { llSensorRepeat("","",AGENT,Range,PI,Rate); } sensor(integer num_detected) { id = llDetectedKey(0); integer i=0; while (i<num_detected) { if (llGetListLength(visitors)<9) { PositionInList=llListFindList(visitors,[llDetectedName(i)]); if (PositionInList==-1) { visitors=visitors+llDetectedName(i); } if (PositionInList!=-1) { llSay(0,"You're already on the list"); } } if (llGetListLength(visitors)>9) { llTeleportAgent(id,"",LandingPoint,LookAt); } } ++i; } }
  20. Thank you very much for your quick reply. I tried to implement your suggestions and ended up using an older script of yours as a help, which I found here: So it seems to be going in the right direction. The teleporter starts after the given time, and it works on multiple avatars. There is probably still a lot of room for improvements, so feel free to comment further. I might come back for more detailed questions on this later. For now, thank you very much, again! float SCAN_RANGE = 20.0; float SCAN_INTERVAL = 90.0; string dest = "you_region"; vector land = <20.0,61.0,22.0>; vector look = <1.0, 1.0, 1.0>; key id; list gVisitors; // Save Visitor UUIDs list gVtime; // Save visit times integer seconds; default { state_entry() { llSetTimerEvent(180.0); // Start a 180 seconds garbage collector llSensorRepeat("", NULL_KEY, AGENT_BY_LEGACY_NAME, SCAN_RANGE, PI, SCAN_INTERVAL); } sensor(integer number_detected) { id = llDetectedKey(0); integer temp = llListFindList(gVisitors,[id]); if(~temp) //Has the Av visited before? { //Subtract saved Unix time from current Unix time. Was it it > 90 seconds ago? if((llGetUnixTime() - llList2Integer(gVtime,temp)) > 90) { // If yes ..... gVisitors = llDeleteSubList(gVisitors,temp,temp); //Remove Av from visitor list gVtime = llDeleteSubList(gVtime,temp,temp); // Remove Av's visit time too llInstantMessage(id, "Teleporting you to : "+ dest); osTeleportAgent(id, dest, land, look); } } else //No previous visit { llRegionSayTo(id,0,"You will be teleported back in 90 seconds."); gVisitors += [id]; // Add to the Visitor list gVtime += [llGetUnixTime()]; // Add current Unix time to the time list } } timer() //Every 180 seconds ... { integer i; for (i=((gVisitors !=[])-1);i>=0;--i) //Look through all the saved visitor times { // For each one ... if((llGetUnixTime() - llList2Integer(gVtime,i))> 180) // If it was more than 270 seconds ago ... { gVisitors = llDeleteSubList(gVisitors,i,i); // Remove the person from the Visitor list gVtime = llDeleteSubList(gVtime,i,i); //Remove the visit time from the list } } } }
  21. Hi again! I have an area on my sim in which avatars are only supposed to remain for a certain limited time. 1. The avatars arriving are put on a list. 2. Each avatar on that list is individually given the same time span to remain in that area and then is teleported back to his / her starting point. 3. Once the avatar has been teleported, the avatar has to be taken off that list to make sure that should the avatar return to that area, the same procedure will start again. I have a script that roughly does this with one avatar, but not with multiple ones. Do you maybe have an idea of how to adjust this script so that multiple avatars arriving in that area will be teleported after an equal time span? Thank you very much in advance! vector LandingPoint = <20,61,22>; // X,Y,Z landing point for avatar to arrive at vector LookAt = <1,1,1>; // which way they look at when arriving// integer seconds; integer RESPONSE_CHANNEL = -100; float SCAN_RANGE = 10.0; float SCAN_INTERVAL = 2.0; list VISITOR_LIST; key this_agent_key; default { state_entry() { llSensorRepeat("", NULL_KEY, AGENT_BY_LEGACY_NAME, SCAN_RANGE, PI, SCAN_INTERVAL); } sensor(integer number_detected) { integer agent_number; //iterate through all detected agents for (; agent_number < number_detected; agent_number++) { string this_agent_name = llDetectedName(agent_number); this_agent_key = llDetectedKey(agent_number); //if the agent is not found on the list if (llListFindList(VISITOR_LIST, [this_agent_name]) == -1) { //add her/him and make the list hold the last 200 visitors VISITOR_LIST = [this_agent_name] + llList2List(VISITOR_LIST, 0, 198); llOwnerSay(this_agent_name); llSetTimerEvent(1.0); } } } timer() { ++seconds; if(seconds == 15) { llInstantMessage(this_agent_key, "Your time is up.\n \n \nTeleporting you to ... "); llTeleportAgent(this_agent_key, "", LandingPoint, LookAt); } } }
  22. Thank you very much! I tried it with less text and it worked. This might have been the solution. Thank you very much again!
  23. Hi! I've got a script that uses notecards and displays the text on these notecards on its textures, as a kind of notice board. It automatically adds some line-breaks when the sentence is too long for the surface area. Unfortunately, this does not always work, which means sometimes the last letters of a word disappear. Maybe one of you has an idea of how to change this part, so that the words are no longer cut off at the end? Thank you very much in advance. Here is the script: string title = ""; string subtitle = ""; string text = ""; string add = ""; integer xt = 40; // position x titre integer ligne; integer ligne2; integer ligne3; integer ligne4; integer ligne5; key demandetitre; key demandesub; key demandetext; key demandeimg; key demandeoption; string color; string color2; string color3; string color4; integer imgw; integer imgh; integer imgx; integer imgy; integer fin; integer alpha; push_text2() { draw_text(); } draw_text() { string drawList =""; if (add!="") { drawList += "MoveTo " + imgx + ", " + imgy + ";Image " + imgw + ", " + imgh + "," + add + ";"; } drawList += "MoveTo "+xt+",80; PenColour " + color + "; FontSize 48; Text " + title + ";"; drawList += "MoveTo 40,160; PenColour " + color2 + "; FontSize 32; Text " + subtitle + ";"; drawList += "PenColour " + color3 + "; MoveTo 40,220; FontSize 24; Text " + text + ";"; osSetDynamicTextureData("", "vector", drawList, "width:1024,height:1024,alpha:"+alpha+",bgcolour:"+color4, 255); } default { on_rez (integer rez) { llResetScript(); } state_entry() { } dataserver(key requested,string message) { integer nbrchar; integer i=0; integer j; integer k; string com; string message2; if (requested==demandetitre&&message!=EOF) { if (ligne==1) { color=message; } else { nbrchar=llStringLength(message); if (nbrchar>25) { title="ERROR"; xt=512-(8/2*38+40); } else { title=message; title=llToUpper(title); xt=512-(nbrchar/2*38+40); } } demandetitre=llGetNotecardLine("Title",ligne++); } if (requested==demandesub&&message!=EOF) { if (ligne2==1) { color2=message; } else { nbrchar=llStringLength(message); if (nbrchar>37) { subtitle="ERROR"; } else { subtitle=message; } } demandesub=llGetNotecardLine("Subtitle",ligne2++); } if (requested==demandetext&&message!=EOF) { if (ligne3==1) { color3=message; } else { nbrchar=llStringLength(message); if (nbrchar>60) { i=nbrchar/60; message2=message; for (j=i ; j>0 ; j--) { k=j*60; message2=llInsertString(message2,k,"-\n"); } message2 += "\n"; text += message2; } else { text += message; text += "\n"; } } demandetext=llGetNotecardLine("Text",ligne3++); } if (requested==demandeimg&&message!=EOF) { if (ligne4==1) { imgw=(integer)message; } if (ligne4==2) { imgh=(integer)message; } if (ligne4==3) { imgx=(integer)message; } if (ligne4==4) { imgy=(integer)message; } if (ligne4>4) { add=message; } demandeimg=llGetNotecardLine("Picture",ligne4++); } if (requested==demandeoption&&message!=EOF) { if (ligne5==1) { alpha=(integer)message; } if (ligne5==2) { color4=message; } demandeoption=llGetNotecardLine("Option",ligne5++); } if (message==EOF) { fin++; } if (fin==5) { push_text2(); } } changed (integer change) { if (change & CHANGED_INVENTORY) { ligne=0; ligne2=0; ligne3=0; ligne4=0; ligne5=0; text=""; title=""; subtitle=""; add=""; fin=0; alpha=0; demandetitre=llGetNotecardLine("Title",ligne++); demandesub=llGetNotecardLine("Subtitle",ligne2++); demandetext=llGetNotecardLine("Text",ligne3++); demandeimg=llGetNotecardLine("Picture",ligne4++); demandeoption=llGetNotecardLine("Option",ligne5++); } } }
  24. 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(); } }
  25. I'm still not quite there yet. I'll post more next week. Thanks everyone!
×
×
  • Create New...