Jump to content

Ruthven Ravenhurst

  • Posts

  • Joined

  • Last visited

Everything posted by Ruthven Ravenhurst

  1. llGetNumberOfPrims will give you the number of links including seated avatars, as you clearly already know. llGetObjectPrimCount(llGetKey()) will give the prim count without the avatars. So for example a car with 4 seaters would be, say 20 prims, but the car by itself would be 16 prims. So the seated avatars prim numbers would be 17, 18, 19, 20 You could run a loop to get those numbers.
  2. I assume this is a worn object, based on the names of some of the globals. You have it resetting on rez. If it's worn already when you log in, that's triggering the on rez event. Remove or comment out the reset function there and it should be fine
  3. This example on LlSetKeyFramedMotion does just that. It does use a sensor, but you could easily change it to a timer that polls for the position and rotation of the avatar/object it's following. The benefit of the timer is you could get that info from across the sim and at a much larger height, rather than the limit of 96m in the sensor
  4. If you only need 2 different timers, there is the sensor event. You can have it look for an avatar with it's own key as the name, and with a very short range. This will trigger the no_sensor event, where you can set the second timer functions. Another one is to give each timed function a number Global: GTimer; //1 for a sound, 2 for a light, 3 for saying something. Set the numbers to match the thing you want to happen when the timer goes off Each time you need to use llSetTimerEvent, set GTimer to the appropriate number { ... other things in this event...; GTimer = 1; llSetTimerEvent (10.0) } timer () { if(GTimer == 1) { llPlaySound("sound name", 0.5); } else if(GTimer == 2) { ... function (s) to set lights... } else if(GTimer ==3) { llSay(0, "this is timer mode 3"); } GTimer = 0;//reset to 0 so nothing happens if timer goes off llSetTimerEvent (0);//turn the timer off } Hope this helps
  5. Yes, sort of. You'll need to bring the gif into a photo editing software and break up the layers into a grid, and turn it into a flat texture used with llTextureAnim. There may be some online generators that can do that for you.
  6. Also this will eventually break the script. If the end user drops something into the inventory, the script will reset, and it won't be able to get the key of the non-fullperm notecard in state_entry again
  7. This forum is for help with scripts you are working on. If you want someone to make a script for you, post in the Wanted forum, or In World Employment. You likely won't get someone to make it for free either, but it could be a fun project for someone that wants to. Edit to add: And now I see you posted the same request almost a day ago in another forum, and someone else told you basically the same thing....🤷‍♂️
  8. Something like alt-text in a browser? Unfortunately there's no way to do that in lsl😕 The closest you'd get to that on an object is the hover tips with all the info, but that doesn't work on attachments as far as I know.
  9. Yeah, if I was to make one with llTakeControls, I would have it not pass controls to ither6 scripts and for pose change/movement I'd use: Page Up/Down: Next/Previous* I thought these were options? Arrows keys for moving avatar left, right, forward, backward. Mouse Left to turn left Mouse Right to turn Right* Nevermind, guess this isn't an option. And to rotate forward/backward, umm....
  10. Use llGetAgentSize. If it returns zero_vector, wait a few seconds and try again
  11. Try it like this? Capturing it as a key, then listing it inside the function list List = ["n","n","13056ed9-7351-446d-b7ee-3152aeffed1a"];default{ touch_start(integer total_number) { key TOUCHER = llDetectedKey(0); integer found = ~llListFindList(List,[TOUCHER]); if(found){llSay(0,"Found");llSay(0,(string)found);} else{llSay(0,"Not Found");llSay(0,(string)found);} }}
  12. Also this should be an && test, as the OR will always result to true in this case, so: if((number != 10006) && (number != 10008))
  13. 😀 llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHANTOM,( llDetectedType(0) & AGENT)]);
  14. can also do toggle = -toggle; float toggle = 1.0;//can keep as integer you want, but it's being converted to a float in the vector anyways default { touch_start(integer total_number) { llPlaySound(DOOR_SOUND, VOL); toggle = -toggle; llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POS_LOCAL, llList2Vector(llGetLinkPrimitiveParams(LINK_THIS, [PRIM_POS_LOCAL]), 0) + <toggle, 0.0, 0.0 >]); } }
  15. think i figured it out, but there's gotta be a more efficient way of doing it 😕 it's getting the time when the loop is about to start, then replaces the unix time in the temp list with the time since that player's score was last updated. formatted by lumping it together as "score-timesince-name" then sorting, it sorts how i wanted it to. then it parses each of those lumped strings, then converts the timesince back to the original unix time, and reconstructs the score list list scores = [15,2001,"player 1", 12,2004, "player 2", 19,2004, "player 3", 15,2002, "player 4", 12,2005, "player 5"]; default { state_entry() { list temp = []; integer i; integer len = llGetListLength(scores); integer now = 2006; for(i = 0; i < len; i += 3) { integer score = llList2Integer(scores,i); integer since = now - llList2Integer(scores, i+1); string name = llList2String(scores,i+2); temp += llDumpList2String([score,since,name],"-"); } llOwnerSay(llList2CSV(temp)); temp = llListSort(temp,1,FALSE); llOwnerSay(llList2CSV(temp)); len = llGetListLength(temp); scores = []; for(i = 0;i < len; i++) { list temp2 = llParseString2List(llList2String(temp,i),["-"],[]); integer score = llList2Integer(temp2,0); integer time = now - llList2Integer(temp2,1); string name = llList2String(temp2,2); scores += [score,time,name]; } llOwnerSay(llList2CSV(scores)); } } //returns: [21:35] 15-5-player 1, 12-2-player 2, 19-2-player 3, 15-4-player 4, 12-1-player 5 [21:35] 19-2-player 3, 15-5-player 1, 15-4-player 4, 12-2-player 2, 12-1-player 5 [21:35] 19, 2004, 2006, 15, 2001, 2006, 15, 2002, 2006, 12, 2004, 2006, 12, 2005, 2006 [21:35] 15-5-player 1, 12-2-player 2, 19-2-player 3, 15-4-player 4, 12-1-player 5 [21:35] 19-2-player 3, 15-5-player 1, 15-4-player 4, 12-2-player 2, 12-1-player 5 [21:35] 19, 2004, player 3, 15, 2001, player 1, 15, 2002, player 4, 12, 2004, player 2, 12, 2005, player 5
  16. I'm trying to figure out how to sort a list of scores, and names, but maintain the player's place on the scoreboard if someone ties with them. for example, player 1 has a score of 15, then player 3 gets a score of 15, player 1 should stay in 1st place, and player 3 should move up to second place. following? i used the following script, but it didn't maintain the places as i expected. list scores = [15,"player 1", 12, "player 2", 19, "player 3", 15, "player 4", 12, "player 5"]; default { state_entry() { scores = llListSort(scores, 2, FALSE); llOwnerSay(llList2CSV(scores)); } } //Returns: [19:42] 19, player 3, 15, player 4, 15, player 1, 12, player 5, 12, player 2 So i thought what about adding another "column" of the unix time when that player last scored. but i don't know how i'd go about sorting the list both by the scores descending, and the unix time ascending. someone suggested crunching the score, unix time and name together in a string, sorting, then extracting them again, but that didn't work either, and sorts it the same way since the lower unix time added to the same score is also going to sort in descending order list scores = [15,2001,"player 1", 12,2004, "player 2", 19,2004, "player 3", 15,2002, "player 4", 12,2005, "player 5"]; default { state_entry() { list temp = []; integer i; integer len = llGetListLength(scores); for(i = 0; i < len; i += 3) { temp += llDumpList2String(llList2List(scores, i, i+2),""); } llOwnerSay(llList2CSV(temp)); temp = llListSort(temp,1,FALSE); llOwnerSay(llList2CSV(temp)); scores = llListSort(scores, 3, FALSE); llOwnerSay(llList2CSV(scores)); } } //returns: [20:32] 152001player 1, 122004player 2, 192004player 3, 152002player 4, 122005player 5 [20:32] 192004player 3, 152002player 4, 152001player 1, 122005player 5, 122004player 2 [20:32] 19, 2004, player 3, 15, 2002, player 4, 15, 2001, player 1, 12, 2005, player 5, 12, 2004, player 2
  17. that's not something you can do with a script. it has to be done with the edit window https://gyazo.com/1a7ff76e1774f8409220004229949d4d
  18. Sensors. I have a gargoyle statue that breathes fire at people targeted from a sensor. The sensor needs to come from the mouth. The sensor range/arc/direction can be customized via script, and resides in a sphere shape to visualize the sensor by matching the dimple and size of the sphere to arc and range. The rotation of the sphere determines the direction of the sensor. Thinking on it now, this could be done with llGetAgentList on a timer and setting a box shaped area rather than a pointed sensor that can easily be tricked (imagining someone walking along the wall under a camera to stay out of the camera's view).
  19. Unfortunately yes. And there's not really an easy way to find the edge of a parcel. As long as the parcel is a rectangle/square shape. Starting at the lowest numbers of the parcel coordinates, and checking for the same parcel id every 4m up and to the side you can find the edges. But parcels don't necessarily need to be a square shape, they can have cut outs, being and diagonal having many borders on different x or y coordinates, there can be holes. They can have another parcel run across it cutting it into what appears to be 2 parcels. I'm on my phone right now, otherwise I'd try to come up with a couple snippets of a script for finding the edges (under the assumption that the parcel is one square shape) and also figure out if the avatar is at least some determined amount of meters from those edges
  20. that's because llRequestAgentData triggers another data event like reading the notecard, and the key you're seeing is the data event key this should work.... string NOTECARD = "keylist"; //Name of notecard containing group member keys key namekey; key resident; integer intLine1 = 0; default { state_entry() { namekey = llGetNotecardLine(NOTECARD, 0); } dataserver(key keyQueryId, string Data) { if(keyQueryId == namekey) { if(Data != EOF) { llOwnerSay("namekey = " + (string)Data); //test to check notecard read ok resident = llRequestAgentData(Data, DATA_NAME); } else { llOwnerSay("End of notecard"); } } else if (keyQueryId == resident) { llOwnerSay ("Resident = " + resident); namekey = llGetNotecardLine(NOTECARD, ++intLine1); } } touch_start(integer x) { llResetScript(); } }
  21. I like this one a lot. you can set multiple ones out and if any of them overlap, only the closest one to the avatar will repeat it. i've modified it slightly so that it won't repeat to anyone that's not within 20m of any of the relays, and won't repeat to anyone that's within 20m of the avatar speaking Parcel Chat Relay
  22. Since you're removing the listen the timer, you could have it assign a random number when Touched touch_start(integer total_number) { llListenRemove(gListener); integer chan = (integer)llFrand(-99)-99; gListener = llListen(chan, "", llDetectedKey(0), ""); llDialog(llDetectedKey(0), "\nyour answer is?", ["Yes", "No" ] , chan); llSetTimerEvent(60.0); }
  • Create New...