Jump to content

KT Kingsley

  • Content Count

  • Joined

  • Last visited

Community Reputation

495 Excellent

About KT Kingsley

  • Rank
    Advanced Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. How much data needs to be saved? If it's something like daily, or hourly, footfall – something that'll build into a huge number of items, then perhaps the key-value pairs feature of an experience might work. Otherwise you'll probably have to consider some form of external data storage, accessed by HTTP, perhaps something like Google Sheets (which is, by all accounts, rather fiddly to set up for this, but quite effective – I've not tried using it myself), or maybe a custom data storage service. Another possibility is to create a dedicated data storage script; one that'll never be reset and which communicates with the main script via link messages to save and return values. If you just need to store something like a cumulative total, or half a dozen or so values, then you could use the object's description or various object parameters like face colour settings. Using a notecard for backup can be done by having the script chat out (or IM or email, like Rolig says, above) its stored data, which you then copy and paste into a notecard manually, and which can then be read back in by the script automatically.
  2. The second script you've posted will never work: you have lists inside lists: [llParseString2List(listener,[""],[" "])] [newentry] The result of llParseString2List is a list, so putting it inside brackets is putting a list inside a list. And the same applies to newentry. In the llListSort call you set a stride of 1. I think you mean 2 there. In the llParseList2String call you don't specify any separators, but you do include a space in the spacers. Separators are discarded, while spacers are included in the list as items in their own right. I think you want them the other way around. Also, a slightly neater way to see what a list contains is to use the function llList2CSV which separates the list items from each other with commas. I think the example below might be what you're looking for: list newentry=[]; list allbest=[]; default { state_entry() { llListen(-3500, "", "", ""); } listen(integer channel, string name, key id, string listener) { newentry=newentry+llParseString2List(listener,[" "],[]); allbest=llListSort(newentry,2,TRUE); // llSay(0,"output:"+(string)allbest); llOwnerSay ("Output: " + llList2CSV (allbest)); } }
  3. Yeah, sorry, you're right. I was confusing this with the situation with permissions and changes, which is completely different.
  4. Aren't things going to get a bit wonky if you try to combine conditions like that? For example, if (CONTROL_ML_LBUTTON & click & held) will return TRUE if either click or held are TRUE, as it takes only a single bit to be set for the result to be TRUE. Using that example, don't you need an expression like if ((CONTROL_LBUTTON & click) && (CONTROL_LBUTTON & held)) or if (CONTROL_LBUTTON & (click | held)) == (click | held))?
  5. It's reacting to both the edge caused by pressing the button and to the edge caused by releasing the button. To have it react to just the button press, check the level – whether the button is pressed – as well as the edge: if (edge & (CONTROL_LBUTTON) && level & (CONTROL_LBUTTON))
  6. May I mention the land_collision_start event here: unlike collision_start this is triggered by a collision with the ground.
  7. I have a sub-folder in my "#RLV" folder called "Outfits". I use the RLV command "@getinv:Outfits=2222" to get the names of the individual outfit sub-folders in that. The RLV command returns their names as a CSV (comma separated values) chat message on, in this example, channel 2222. I convert those CSVs, using llCSV2List, to a list of button names that goes into the menu function llDialog. And the return from that, plus the outfit folder name, goes into the example I gave. integer rlv_listener; integer dialog_listener; default { touch_end (integer total_number) { rlv_listener = llListen (2222, "", "", ""); // create a listener to listen for the result of the RLV command llOwnerSay ("@getinv:Outfits=2222"); // get a list of the folders inside the folder "#RLV/Outfits" } listen (integer channel, string name, key id, string message) { if (channel == 2222) // this is the result of the RLV folder query { llListenRemove (rlv_listener); // remove the listener list buttons = llCSV2List (message); // convert the result to a list dialog_listener = llListen (3333, "", "", ""); // create a listener to listen for the result of the dialog llDialog (llGetOwner (), "\nSelect an outfit:", buttons, 3333); // create a dialog using the buttons list } else if (channel == 3333) // this is the result of the dialog { llListenRemove (dialog_listener); // remove the listener llOwnerSay ("@detach=n"); //don't detach this HUD llOwnerSay ("@detachthis:Outfits/" + message + "=n"); //don't detach anything you're already wearing that's also in the target folder llOwnerSay ("@detach=force"); //detach all your other attachments llOwnerSay ("@remoutfit=force"); //remove all your other system clothing llOwnerSay ("@attachall:Outfits/" + message + "=force"); //attach everything in the target folder llOwnerSay ("@detachthis:Outfits/" + message + "=y"); //reenable detaching items in the target folder llOwnerSay ("@detach=y"); //reenable detaching this HUD } } } This is a pretty basic script without any error handling or error prevention. It doesn't include any timeouts, it doesn't check the RLV message contents for suitability as button labels, and it doesn't do anything about multiple unexpected clicks.
  8. We can only hope that the source email address is distinctive enough that it can be blacklisted in our email services without also blacklisting the stuff from LL and SL that we actually want. I can't help thinking that this won't help the Lab's attempt to shed its reputation as a spamming service, which led to the introduction of verified email addresses.
  9. Not sure I like the sound of this. https://releasenotes.secondlife.com/simulator/2020-03-27T23:25:44.539377.html
  10. And, I just noticed, you'll need a no_sensor event in the grenade script for when your aim is off (or you're just playing around) and the grenade lands more than 5 metres away from an avatar.
  11. In that example I did comment out the redundant llResetScript call. I'll edit my post to delete it altogether, to avoid confusion.
  12. Oh, and so as not to start the timer when you rez the grenade from your inventory to edit it, you could test if the on_rez parameter is not 0 (the llRezAtRoot functions in the thrower script set a parameter of either 1 or 10, depending on the mode). So: on_rez(integer num) { if (num) llSetTimerEvent(3); }
  13. How does the thrower object work? Does it rez the grenade with a velocity, using llRezObject or llRezAtRoot? Or is it something like a physical catapult? One thing you could try is to have the timer start when the grenade is rezzed, in the on_rez event, rather than when the script is saved or reset, in the state_entry event: state_entry() { llParticleSystem([]); } on_rez(integer num) { llSetTimerEvent(3); } //etc... Edit: I just saw your link to the thrower script, and it does use llRezAtRoot, so I think my suggestion above should do the trick.
  • Create New...