Jump to content

Quistess Alpha

Resident
  • Posts

    3,876
  • Joined

  • Last visited

Everything posted by Quistess Alpha

  1. Not complicated, but from the few time's I've done it from scratch, there are a good few gritty details to debug (half tile offset might only be needed for even # total columns/ rows; the need to use both negative and positive offsets to avoid literal edge cases). Thanks for posting an example!
  2. Would actually be kind of doable with RLV, but I dunno the overlap of 'people who would be ok with RLV' and 'people who would want to live in an SL appartment'.
  3. Exactly. There are plenty of ways of handling a "Sorry, I have already been used" state, and I guess with linkset data that's even easier to do "securely", but just being absolutely sure the object is destroyed with llDie seems the least "messy".
  4. attach(key ID) { if(ID) { llSay(channel,"I have been attached"); }else { llSay(channel,"I have been detached"); } } from the attachment, otherwise, you'd have to loop through llGetAttachedList() on a timer.
  5. Thinking on it a bit more, the easiest 'hack' for the MP would be to set up a no-copy 'voucher' item similar to how some gachas worked: you buy the voucher on the MP, then when you rez (but not attach, the script needs to prevent that) the voucher, it emails the in-world vendor and deletes itself when the vendor responds (preferably via http). The vendor then acts as it would if the voucher's owner had bought the item with L$.
  6. Hmm, yes if you wrote a custom vendor, you could llEmail() it (or a permanent prim in a secure location that had been communicated with) if you don't have the timestamp. I think it ~might be theoretically possible to scrape marketplace (MP) info if the prim can 'log in' as the creator to the MP, but I don't know if LSL is sophisticated enough to make that kind of http transaction.
  7. Personally, I prefer using the physics functions to operate simple vehicles rather than the vehicle functions. As for 'going up steps' try decreasing your vehicle's gravity in the build menu or with llSetPhysicsMaterial and add some invisible 'sleds' to your vehicle's physics shape; a half-sphere with the bottom flattened a bit might do the trick. (dimple 0.5, 0.9 ish? set physics type convex)
  8. FWIW, here's the function I use to push things to discord's webhook: uSendDiscord(string content,string name,string hook) { list lst = ["content",content]; if(name) lst+= ["username",name]; string send = llList2Json(JSON_OBJECT,lst); llHTTPRequest(hook, [ HTTP_METHOD, "POST", HTTP_MIMETYPE, "application/json" ], send); } which usually works well enough for most things (there are more usable json fields in the documentation, but I haven't had much need of them). I know I could "optimize" it, but it's not something that's to be run frequently (by 'things that should be optimized' standards).
  9. Thank you for your hard work making that a thing without whatever black magic the other viewers are still using!
  10. Not to belabor the point, but yes there are optimizations you can do depending on context, (I.E. use global variables for list literals) and how you shuffle the (in)efficiency around between execution speed and memory usage is also context dependent (that said, if you want to be space-efficient, I'd argue you shouldn't be trying to make dictionaries in the first place)
  11. You can look in the environment section of the 'about land' window, but that obviously doesn't apply to personal environments.
  12. There might be viewer-specific possibilities, but the easiest solution would be to sit on something that has defined camera position prim properties. (FOV isn't changeable by script though :/) // usage instructions: // - put the script in a prim, and make sure it is set to running, then sit on the prim. // - move your camera to somewhere of interest. // - say "setCam" (one word, with a capital C, no quotes) // - stand up, then sit back down on the prim. // - for as long as you are sat on the prim, pressing 'escape' willrestore your camera to where it was when you said "setCam". integer ghListen; default { state_entry() { llSetClickAction(CLICK_ACTION_SIT); llSitTarget(<0,0,0.25>,ZERO_ROTATION); } changed(integer c) { if(c&CHANGED_LINK) { key av=llAvatarOnSitTarget(); if(av) { llRequestPermissions(av,PERMISSION_TRACK_CAMERA|PERMISSION_TRIGGER_ANIMATION); ghListen = llListen(0,"",av,"setCam"); }else { llListenRemove(ghListen); } } } run_time_permissions(integer perms) { if(perms&PERMISSION_TRIGGER_ANIMATION) llStopAnimation("sit"); } listen(integer Channel, string Name, key ID, string Text) // { if(llGetTime()>3.0) { if(llGetPermissions()&PERMISSION_TRACK_CAMERA) { vector myPos = llGetPos(); rotation myRot = llGetRot(); vector camPos = llGetCameraPos(); rotation camRot = llGetCameraRot(); llSetCameraEyeOffset((camPos-myPos)/myRot); llSetCameraAtOffset(((camPos+llRot2Fwd(camRot))-myPos)/myRot); llRegionSayTo(ID,0,"Camera changed. Try unsiting, then re-sit and press escape."); } } } }
  13. If you need to do it in such a way that users can't pretend to be someone else (at least not without that person's cooperation), you need to use encryption. This is exactly the scenario for which I ported the XTEA algorithm to LSL: (quoted to minimize long code spam)
  14. I think the best way to do it would be to have the form send back the user's key* with the form data. There are multiple ways to achieve that, but if it were me, I'd add the user's key as part of the form url's query string when generating the page's (X)HTML. *Usernames are changeable; keys are not. Best practice is to use a user's key to identify them, not their name. Use names only for presentation to users.
  15. Oops, and my push_to_JSON_LSD function has a few errors as well ( need to use the values in the separators parameter instead of literals, and llParseString needs an extra empty list parameter ). If/when I need to use JSON I never write the literal string anyway, it's safer to generate it with llJsonSetValue or llList2Json. string message; message = llJsonSetValue(message,["command"],"CMD"); message = llJsonSetValue(message,["param1"],"value1"); // etc. JSON seems very 'love it or hate it'. I used to rather dislike it, but I've come around slightly. If you need a key-value store within a string, using native LSL functions is more "natural" than making user functions, and if you're looking for efficiency, the comma-sepparated-value (CSV) conversion functions are pretty robust (correct handling of 3 or 4 valued vectors (vector/rotation), even though they contain commas), if you can handle a fixed argument order.
  16. Not relevant to this discussion, but as an aside, llDialog ( and llTextbox ) responses come with the sending object as the avatar, but the sending ~location as the object which called the function. In practice, this means that if the object making the llDialog call is the same one that is listening for the response, it will always be heard as long as the avatar's viewer is able to send the response* . dialog boxes on channel 0 could be used for (very loud) role-play telephones. *sometimes works for a few seconds after tp to a very distant region, local distance is loosely related to the viewer's draw distance.
  17. For what it's worth, gmail is quite nice for spamming different addresses for accounts: You can add a "+tag" to the end of your address, so myEmail+secondlife@gmail.com and myEmail+secondlifeAlt@gmail.com both get routed to the owner of myEmail@gmail.com. Some sites don't think '+' is a valid character in email addresses. To bully them, you can infix '.' anywhere in the address before the '@': like my.Email@gmail.com or m.y.e.m.a...i.l@gmail.com .
  18. Presuming you have a choice over the message protocol, it's probably better to leverage built-in functions for JSON: // if you're being really persnickety about execution time, define all static lists in global variables: list gCOMMAND = ["COMMAND"]; list gPARAM1 = ["param1"]; list gPARAM2 = ["param2"]; //... // presumably, you get the message from a listen event, or possibly http communication: string message = "{COMMAND=CMD,param1=value1,param2=value2}"; string CMD = llJsonGetValue(message,gCOMMAND); if(CMD=="Command1") { string param1 = llJsonGetValue(message,gPARAM1); string param2 = llJsonGetValue(message,gPARAM2); // and so on, then do something with the parameters. } https://wiki.secondlife.com/wiki/Json_usage_in_LSL You can even convert to JSON from |, = format: integer push_message_to_JSON_LSD(string message, list separators); // { string message = "CMD|param=value|param2=value2"; integer ind = llSubStringIndex(message,"|"); string command = llDeleteSubString(message,ind,-1); // if the message has no "|", the final character will be deleted. message = llDeleteSubString(message,0,ind); if(message) { message = llList2Json(llParseString2List(message,["|","="])); llLinksetDataWrite("Dict:"+command,message); return TRUE; } return false; } string read_JSON_LSD(string cmd, string param) { string ret = llJsonGetValue(llLinksetDataRead("Dict:"+cmd),param); if(ret==JSON_INVALID) return ""; return ret; } //example usage: string message = "CMD|param=value|param2=value2"; push_message_to_JSON_LSD(message,["|","="]); string value = read_JSON_LSD("CMD","param"); // should == "value" from the message. (not debugged) Something like that might be a medium between your method 1 and 2, slightly less efficient than 1 on the read, but possibly more efficient than 1 on the write.
  19. you'd need to research the specific head in question, each of the common head brands is slightly different. If you mean you meshed the head yourself, that's a bit more work than just dropping in a script that 'makes it do the thing you expect it to'.
  20. did you try llKeyframeMotion? it's a bit harder to get a handle on for things like this though.
  21. On android, there's a wonderful keyboard app called "unexpected keyboard" that can type pipes and other fancy symbols easily. As for the script, in situations where exactly one animation is supposed to play, it's usually best to just have a global variable set to the running animation, so you can run_time_permissions(...) { if(perms&PERMISION_TRIGGER_ANIMATION) { if(gAnimOld) llStopAnimation(gAnimOld); if(gAnimNew) { llStartAnimation(gAnimNew); gAnimOld=gAnimNew; gAnimNew=""; } } } or so. (pro-tip: set the old animation to "sit" to stop the default sitting animation) setting a global variable to the anim you want to play and requesting permissions every time, stops your script from complaining if a sitter uses "reset skeleton and animations".
  22. I was using packets in an anecdotal sense, no clue about server implementation either...
  23. IIRC, LSL http stuff still has occasionally frustrating low character limits. Hmm, reading the wiki, so, the messaging protocol for maximum data transfer is a little convoluted.
  24. A few months ago, if this is the one.
  25. Some outfits from Meli Imako, but they might be a bit too formal: https://marketplace.secondlife.com/p/MAITREYA-FULL-PERM-FITMESH-Working-Woman-Character-Outfit/17839264 https://marketplace.secondlife.com/p/Full-Perm-Female-Waitress-Uniform-Slink-Maitreya-Legacy-Belleza-Tonic-Ebody-Ocacin-Classic-Body/11291431
×
×
  • Create New...