Jump to content

Fenix Eldritch

Resident
  • Posts

    771
  • Joined

Everything posted by Fenix Eldritch

  1. For a list within the current linkset, you can use llGetLinkPrimitaveParams and PRIM_SIT_TARGET. For a list of external objects or linksets, you're more limited. llGetObjectDetails does not have an equivalent constant for sit targets. It does, however, have OBJECT_CLICK_ACTION and CLICK_ACTION_SIT... which you could use to infer that a sit target has been potentially set on the prim. But that is not guaranteed to always be the case.
  2. ChatGPT doesn't seem to have the ability to express uncertainty in what it generates, and from what I can see will confidently make up stuff that is demonstrably wrong. This is bad for many reasons, but especially when being used as a reference tool by someone who doesn't know how to code in the first place and therefore cannot spot the flaws. I'm of the opinion that ChatGPT is a poor substitute for actually leaning how to code. If you want to script things for Second Life, I think your time would be better spent learning how to do it yourself* rather than wrangling the AI and trusting it to not BS you. *And of course, we here on the forums would be happy to answer questions you have along your journey.
  3. You can't define a variable inside the for-loop's parameters like that. Try defining it just before the loop. Also... you have a number of incorrect statements peppered throughout the script. line 15: llGetAnimationLength() is not a valid function. line 36: llSetAnimationOverride() only takes two input parameters, not three. line 42: CHANGED_ANIMATION is not a thing. I only gave this a surface level glance, just poking it till it compiled. Haven't looked into the actual logic, but I would highly recommend consulting the LSL wiki for documentation on how to script. Including going through some of the beginner tutorials.
  4. Of the LinksetData functions, ListKeys will sort the list returned, but FindKeys will not. This is specifically mentioned in the llLinksetDataFindKeys wiki page on the caveats section: You can see this by running the following code, comment/uncomment the function you wish to see in action. default { state_entry() { llLinksetDataReset( ); llLinksetDataWrite("Static║00_girl", " "); llLinksetDataWrite("Static║00_stars", " "); llLinksetDataWrite("Static║00_universe", " "); llLinksetDataWrite("Static║99_number 7", " "); llLinksetDataWrite("Static║99_number 9", " "); //list Pictures = llLinksetDataFindKeys( "^Static", 0,-1 ); list Pictures = llLinksetDataListKeys(0,-1); llOwnerSay(llList2CSV(Pictures)); } } //FindKeys returns: Static║99_number 7, Static║00_universe, Static║00_stars, Static║99_number 9, Static║00_girl //ListKeys returns: Static║00_girl, Static║00_stars, Static║00_universe, Static║99_number 7, Static║99_number 9 This sort discrepancy may be changed in the future, if BUG-232895 is implemented.
  5. This exploit in particular can be mitigated by setting PRIM_SCRIPTED_SIT_ONLY on all relevant objects.
  6. Adding to Innula's post, the entire string of a single prim's hovertext can only be one color at a time. So if you want to have the effect of multiple words or letters having different colors, they are actually separate prims each with their own hovertext.
  7. The only way to show text over an avatar is when they have their group tag active. Anything else is a worn attachment using llSetText. HUDs do not (or at least should not) render at all for anyone other than the owner. This actually resulted in a very interesting mis-feature where a mesh that was rigged to the body, but worn on a HUD attachment point would show the mesh for the owner, but to no one else. I believe that "bug" was eventually squashed. This wiki page lists some of the behavior differences between HUD and non-HUD attachments.
  8. Ah, that'll do it. Open Grid is a separate entity from Second Life and does not have complete parity with SL when it comes to things like LSL functionality and function availability. Another solution that doesn't involve LinksetData would be to instead store the avatar's uuid and access time within a list in the scripts' own memory. I would look at strided lists as a possible application: were each stride contains the avatar's uuid/key and the access timestamp. The thought process would be similar to the previous example: search the list to see if the avatar's key exists within it if the key is found, pull out the associated time and check if it's past the timeout range. if the timeout has elapsed, give the item and update the list with the current time for this avatar if we didn't fined the avatar key in #2, then give them the item and add the avatar's key and timestamp to the list.
  9. "undefined constant/function/variable" means the compiler does not recognize something on the mentioned lines. In this case, I'm guessing it doesn't like the llLinksetData functions. All servers on the Second Life grid should be aware of this new feature, so it shouldn't matter what region you're in when you attempt to compile this script. This does not appear to be the official Linden viewer, so that might be the reason. What viewer are you using and how old is it? If possible, try updating it and see if the problem persists. And if you still get the error, try using a different viewer.
  10. What is the error message you're being given?
  11. Ah, that may complicate things. I don't know how well an automatic translation of the wiki pages might work, but it still may be worth trying it you are interesting in learning to script. Here's a simple demo of what I was talking about in my last post. It uses comments and llOwnerSay commands to narrate what it's doing. It's not a complete solution by any means, but perhaps you can start to tinker with it if you're feeling brave. integer timeout = 60; //number of seconds to wait before giving objec to same person default { state_entry() { llLinksetDataReset(); //empty LSD on startup llOwnerSay("time between giving items to repeat visitors: "+(string)timeout+" seconds"); } touch_start(integer n) { key avatar = llDetectedKey(0); //current avatar ID integer time = (integer)llGetGMTclock(); //current activation time (in seconds) string s = llLinksetDataRead(avatar); //check if avatar is in LinksetData already if(s) //it is was, the value we read won't be empty { integer timediff = time - (integer)s; //difference between saved time and current time //llOwnerSay("test time-currTime: "+(string)time+"-"+s+"="+(string)timediff); //DEBUG if(timediff<0 || timediff>timeout) //if difference is greater than timeout, or negative, give item { llOwnerSay(llKey2Name(avatar)+" is past timeout, give item"); llLinksetDataWrite(avatar,(string)time); //update record } else { llOwnerSay(llKey2Name(avatar)+" is too early: "+(string)timediff); } } else //if avatar wasn't in LinksetData, the value returned will be empty { llOwnerSay(llKey2Name(avatar)+" has no prior record, give item"); llLinksetDataWrite(avatar,(string)time); //update record } } }
  12. Most of programming in general is really just working out the logic; the step-by-step process for what you want to accomplish. What remains is just syntax (what functions you have available to you, the formatting and rules of whatever language you're using). It can be daunting at first, but once you get familiar with things, it can be great fun! The "gentle LSL introduction" I linked above is specifically geared towards those with little to no programming experience, so if you're very new to it, that would be an excellent place to begin. Give it a read, try some of the examples, and if you have questions, definitely ask them here, as we'll be happy to answer. As for your timer question, yes that certainly is possible. As you'll soon learn, there are many ways to accomplish a given task via coding. One possible approach would be to record the uuid of the avatar when they activate the dispenser, along with the time at which they activated it. Store both of those values somewhere (the recently added linkset data would be a good choice). Then, the next time anyone activates the dispenser, it will first compare the uuid of the person currently activating it and see if it has that same value stored away. If it does, compare the time associated with that uuid with the current time and check if it's within the allowed timeout range (i.e. is it older than an hour?) If so, dispense the object again. Otherwise deny giving the object out, because enough time hasn't elapsed.
  13. I think the more pressing question would be "if you wanna learn" The wiki is a wealth of information, and has lots of tutorials. These two would be a good starting point, and they're not too long: A Gentle LSL Introduction A Basic LSL Tutorial As for your project... The typical way to keep track of this would be with a vendor that uses the money event. When a person pays the vendor object, the money event triggers and can run whatever code is in it. There is where you could give out the selected object and if desired, increment a counter that keeps track of sales. However I don't think that will work the same if the object is being sold for L$0, as you can't pay a sum of 0. So instead, I think you'll have to use the touch event to just blindly give out the item to the person who touched the vendor and track accordingly. This is a slightly modified demo using the example code from llGiveInventory's wiki page: integer totalA; //global variable to count times we give out objectA default { touch_start(integer n) { llGiveInventory(llDetectedKey(0), "test_object_A"); totalA++; //increment the ccounter llOwnerSay("we have given out 'test_object_A' "+(string)totalA+" times"); //sample report } } This example assumes one object per vendor, but you can build upon that by using various methods to select different contents to give/track. Such as llDialog, or parsing local chat, or even building prim buttons into the vendor.
  14. You have a lot of extraneous PRIM_LINK_TARGET's in there that you could probably cull. Whenever you specify a link target, all params that follow will continue to target that same preceding PRIM_LINK_TARGET until a new one is specified. For example, this: llSetLinkPrimitiveParamsFast(2, [PRIM_COLOR, iIsLength1, color, 0.0, PRIM_LINK_TARGET, 2, PRIM_GLOW, iIsLength1, 0.0, PRIM_LINK_TARGET, 3, PRIM_COLOR, iIsLength1, color, 0.0, PRIM_LINK_TARGET, 3, PRIM_GLOW, iIsLength1, 0.0, PRIM_LINK_TARGET, 3, PRIM_DESC, sHidden]); Can be written as this: (indentation added for clarity) llSetLinkPrimitiveParamsFast(2, [ //initially targeting link 2 PRIM_COLOR, iIsLength1, color, 0.0, //link 2 PRIM_GLOW, iIsLength1, 0.0, //link 2 PRIM_LINK_TARGET, 3, //now targeting link 3 PRIM_COLOR, iIsLength1, color, 0.0, //link 3 PRIM_GLOW, iIsLength1, 0.0, //link 3 PRIM_DESC, sHidden //link 3 ]);
  15. I think not all of the env parameters directly map to the settings we see in the GUI. SKY_DOME is the geometry that the sky and cloud textures are drawn on. Traditionally in older games, the sky was drawn on a gigantic box that encompassed the scene, hence the term skybox. SL uses a hemisphere which you can see if you engage wireframe mode (Ctrl+Shift+R). The parameter max altitude does actually correlate to the "maximum altitude" seen in the gui, but I'm also not sure what the other two do. Changing them myself via llSetEnvrionment on my parcel don't seem to actually change anything - neither visually nor according to llGetEnvironment which seems to always report the same numbers of offset=0.96 and radius=15000 regardless of what I try to set. Edit: Though if I were to guess, perhaps the offset is the dome's vertical offset from the scene origin, and the radius would probably be the literal radius of the dome. I guess they are locked from being changed? Also I'm not 100% sure, but I think there isn't a parameter specifically for the azimuth of the sun/moon. Rather, we only get the rotation and direction in the bundled SKY_SUN and SKY_MOON parameters.
  16. Aye, this is indeed handy - but be aware it only works when the ID is still in the region. If you hear something from across a region border, llGetOwnerID will return the input ID, giving a false positive on the is-avatar-test without further examination.
  17. I just figured that was because the compiler always does that when tyecasting other types to string - especially since the type specified was a legitimate vector as opposed to a "spoken" vector which would actually be a string as you said earlier. llOwnerSay(llList2String([<1,1,1>], 0)); llOwnerSay(llList2CSV([<1,1,1>])); llOwnerSay((string)[<1,1,1>]); //all three output: <1.000000, 1.000000, 1.000000> llOwnerSay(llList2String(["<1,1,1>"], 0)); llOwnerSay(llList2CSV(["<1,1,1>"])); llOwnerSay((string)["<1,1,1>"]); //all three output: <1,1,1>
  18. Qie's comment is still relevant though in the event that the avatar is wearing an unrelated script that just so happens to be listening on the same channel. While potentially rare, it's not impossible. Sending the message to the avatar is a nice shorthand to target all worn attachments listening on the specified channel, but talking directly to the specific attachment removes any chance of outsiders picking up the message (if that is important for your application, it may or may not matter).
  19. @Anna Salyx I believe this is the issue in question: https://jira.secondlife.com/browse/BUG-232895
  20. Correct, each script should have its own event processing and queue. It would be chaos if they weren't isolated. Edit: I'm not quite sure I follow your uses case as to why you need a second script though... Could you separate them by using a different channel?
  21. As already mentioned, once an event begins, it must finish its execution before another event can run. Newly triggered events will be queued up. clicking on a prim normally results in up to 3 different events (if present in the script): touch_start() triggers when someone first clicks touch() repeatedly triggers as long as someone is holding their click touch_end() triggers when someone releases their click So if you're holding down the click, you'll be triggering multiple touch events. I believe it is entirely possible for a listen event to be queued up and executed in between those touch events if it happens before you (or anyone else who may be presently clicking on it) release the click.
  22. Ah, I forgot to mention in the OP that the commented out segments of my example code will cause compile errors if uncommented (except for "_" as Wulfie explains).
  23. Huh, that's very interesting, it does seem be treated like whitespace. I might file a jira to at least make LL aware of that. It might be useful if later down the line they decide to try adding ternaries and the like. Thanks everyone!
  24. Ah, I should mention this isn't Firestorm. I'm doing this all on the official Linden viewer
  25. Continuing a conversation here so as to not detail another thread. In the referenced thread, a side question was asked if it was allowed to have variable names that start with the "$" character. I did a quick test and found that yes, that's allowed, along with several other characters: default { state_entry() { string `a = "'"; llOwnerSay( `a); //string !b = "!"; //llOwnerSay( !b); //string @c = "@"; //llOwnerSay( @c); string #d = "#"; llOwnerSay( #d); string $e = "$"; llOwnerSay( $e); //string %f = "%"; //llOwnerSay( %f); //string ^g = "^"; //llOwnerSay( ^g); //string &h = "&"; //llOwnerSay( &h); //string *i = "*"; //llOwnerSay( *i); string éj = "é"; llOwnerSay( éj); //string -k = "-"; //llOwnerSay( -k); //string _l = "_"; //this is valid //llOwnerSay( _l); //string =m = "="; //llOwnerSay( =m); //string +n = "+"; //llOwnerSay( +n); //string [o = "["; //llOwnerSay( [o); //string {p = "{"; //llOwnerSay( {p); //string |q = "|"; //llOwnerSay( |q); string \r = "\\"; llOwnerSay( \r); string 's = "'"; llOwnerSay( 's); //string ;t = ";"; //llOwnerSay( ;t); //string :u = ":"; //llOwnerSay( :u); string ?v = "?"; llOwnerSay( ?v); //string <w = "<"; //llOwnerSay( <w); //string ,x = ","; //llOwnerSay( ,x); //string .y = "."; //llOwnerSay( .y); } } //outputs: ' # $ é \ ' ? So... I thought that they were just being accepted as characters in the name. Qie pointed out that variable names can also be suffixed by those characters. And I initially assumed, "yeah obviously, they'll work anywhere in a var name" ... but upon testing that assumption, I find I was wrong. string ?x = "?"; //works string ?x? = "?" //works string x?x = "?" //does not compile And what's more, I just noticed that I can reference the variable name sans special character. string ?v = "?"; llOwnerSay( v); //compiles ok So those aren't even contributing to the var name. Can someone explain what's happening here? And what those characters mean in other programming contexts? The significance is lost on me at the moment. Edit: and this on the official Linden viewer Edit: whoops "_" is a valid and recognized character for var names
×
×
  • Create New...