Jump to content

Messaging all collided avatars


hectic1
 Share

You are about to reply to a thread that has been inactive for 1796 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hi everybody!

Continuing the title of the post, my question is whether I should loop via the num_detected param of collision_start () and collision_end() event handlers for messaging llDetectedKey(i), or can I simply message once llDetectedKey(0).

I couldn't find comprehensive info on the subject, that's why I'm posting here. I definitely want to message a scripted wearable on every colliding avatar, both on entry and on exit of the prim (which is supposed to be primwater btw). And I definitely want to do when multiple avatars are inside the prim-water at the same time.

I tested with my normal avi and my alt (being in and out of the prim at the same time, and separately in and out) and both of the following snippets seem to work. So I can't really tell whether I should loop or not.

I was under the impression that the collided avatars are queued, so I can simply message llDetectedKey(0) every time the event fires, but then I saw the code of a prim-water SwimHUD and they were looping. Which cases does the loop tackle?

Snippets:

...
collision_start(integer num_detected)
{
	integer i = 0;
	for(; i < num_detected; i++) {
		llRegionSayTo( llDetectedKey(i), channel, msg );
	}
}
OR
...
collision_start(integer num_detected)
{
	llRegionSayTo( llDetectedKey(0), channel, msg );
}

 

Link to comment
Share on other sites

Personally, I would go with your second option, but it really doesn't make any difference.  Unless all avs hit the water at precisely the same instant, the situation will default to the second case anyway.  The real challenge you will face is reacting to one and only one collision per avatar.  You'll have to store the UUID of each person and then check against that set of UUIDs every time someone collides, so that you don't get buried in a torrent of duplicate collisions.  And then you will have to decide when to clear the set or remove an individual avatar who is no longer around.

  • Like 1
Link to comment
Share on other sites

That was really fast! Thank you so much for that Rolig! ♥

So, since num_detected will be 0 like 99.99% of the times, I think I should keep the loop to tackle even the rare case of multi avatars entering/exiting the "water" at the exact same time. Unless the loop adds significant runtime overhead or other (please let me know).

Regarding the "reacting to one and only one collision per avatar", I am not sure I understood. Don't collison_start() and collison_end() fire just once per avatar every time they get in and out of the prim?? I mean i do not use collision(), just collision_start() and collision_end()... the rest are handled by the script on the wearable of the avatar (it is just a boolean toggle btw, so i know if the owner of the wearable is in or out of the prim)

Edited by hectic1
typos
Link to comment
Share on other sites

1 hour ago, hectic1 said:

Regarding the "reacting to one and only one collision per avatar", I am not sure I understood. Don't collison_start() and collison_end() fire just once per avatar every time they get in and out of the prim?? I mean i do not use collision(), just collision_start() and collision_end()... the rest are handled by the script on the wearable of the avatar (it is just a boolean toggle btw, so i know if the owner of the wearable is in or out of the prim)

In theory, as you say, an avatar should trigger collision_start just once, upon colliding with you water prim.  In practice, no.  And collision_end is not triggered when the avatar leaves the prim.  A collision is a single event, an action of an instant.  collision_start is triggered by striking the scripted object; collision_end is triggered the instant that the collision ends but, as the caveats in the wiki say, 

  • This event does not always trigger reliably."

As a result, the physics engine apparently has a hard time telling when a collision has actually ended. It may record a new collision even if the avatar has never left the collision prim.  People who script dance floors and trigger prims as doorways always need to watch and be prepared to filter out extra bogus collisions. In your case, it may be just as easy to use a timer and poll ( using llGetObjectDetails) to see whose position is below the water surface rather than detecting collisions at all.   It wouldn't need to be a very fast timer (fire it maybe once a second), and you could turn it on when the first person collides with the water prim and off again when no one is below the surface.

Regarding your original question, events are evaluated in frames that are 1/45 of a second long.  That's why it's quite unlikely that collision_start or touch_start will ever detect more than one triggering avatar at precisely the same instant.  There's no harm in looking for llDetectedKey(1) or llDetectedKey(n), but in practice you will rarely if ever see them.

  • Like 1
Link to comment
Share on other sites

Oh dear God!

Isn't LSL crippled or what? lol

Seems like I have to go into much of otherwise un-needed math, if only events were properly functioning. Thank you very much for that info too Rolig.

I'm not sure I want to go into all that trouble (i think I don't only need to check if llDetectedKey(0) pos.z is below the prim's top face, but if the collided avatar is within the prim-water range in general, right?).

I'll probably just add a couple of buttons on the HUD, letting them "fix" manually cases of missing/misfired events lol

Link to comment
Share on other sites

Heh ..  We can end up doing some odd patchwork scripting at times. I think what's you're trying to do shouldn't really take a lot of work, though.  You could do as you suggest and write a short bit of code to check whether the av is within the volume of your water prim. That's not a bad idea.

  • Like 1
Link to comment
Share on other sites

11 hours ago, hectic1 said:

Isn't LSL crippled or what?

Programming objects in Second Life is more like robotics programming than web programming. You have sensors and actuators, none of which are totally reliable because the world is doing things while you're doing your thing.

  • collision_start and collision_end are not reliable enough to tell when a collision ends. You usually do get collision_start events, though.
  • collision events come in at such a high rate that you can start losing other events.

I do automatic doors by having an invisible phantom prim in the door area to detect when something enters the door area using collision_start. That opens the door. Then I start up an llSensorRepeat with a short range to check for objects in the door area. When it isn't detecting any objects, close the door and stop the llSensorRepeat. (Don't leave it running and using script time.)

"Isn't detecting any objects" means a no_sensor event, or a sensor event that doesn't detect any objects of interest. You may have to ignore your own door or the floor or other fixed objects. I do it this way to open the door for vehicles, animesh NPCs, and other non-avatar moving objects. If you only want your door to open for avatars, it's simpler - just have llSensorRepeat detect avatars only.

This should work for "is somebody in the water?". You might have to check the position of something reported in a sensor event against the bounds of the water.

  • Like 1
Link to comment
Share on other sites

16 hours ago, Rolig Loon said:

Heh ..  We can end up doing some odd patchwork scripting at times. I think what's you're trying to do shouldn't really take a lot of work, though.  You could do as you suggest and write a short bit of code to check whether the av is within the volume of your water prim. That's not a bad idea.

 

13 hours ago, animats said:

Programming objects in Second Life is more like robotics programming than web programming. You have sensors and actuators, none of which are totally reliable because the world is doing things while you're doing your thing.

  • collision_start and collision_end are not reliable enough to tell when a collision ends. You usually do get collision_start events, though.
  • collision events come in at such a high rate that you can start losing other events.

I do automatic doors by having an invisible phantom prim in the door area to detect when something enters the door area using collision_start. That opens the door. Then I start up an llSensorRepeat with a short range to check for objects in the door area. When it isn't detecting any objects, close the door and stop the llSensorRepeat. (Don't leave it running and using script time.)

"Isn't detecting any objects" means a no_sensor event, or a sensor event that doesn't detect any objects of interest. You may have to ignore your own door or the floor or other fixed objects. I do it this way to open the door for vehicles, animesh NPCs, and other non-avatar moving objects. If you only want your door to open for avatars, it's simpler - just have llSensorRepeat detect avatars only.

This should work for "is somebody in the water?". You might have to check the position of something reported in a sensor event against the bounds of the water.

Thank you both so very much for your precious help and your great ideas!! ♥♥♥

For the moment I'll leave the code relying on collision_start() and collision_end().

In my tests it isn't that bad, plus the 2 free swim HUDs I had the chance to look at their code, they both do the same thing. Thor's OAK does keep a list of the collided avatars, but also uses collision_start() and collison_end() so I am not sure what is really doing (looks like it defeats the purpose of keeping an avatars-list so you don't rely on those events).

All in all, my main concern is for my prim-water to work with my wetsense clothing, and it seems to work niclely so far (i also included 2 buttons in the HUD so ppl can tackle manually cases of missing/misfiring events). If I start getting complains, I'll re-visit the subject (the truth is I'm really overwhelmed with fast approaching deadlines atm).

Making the prim swimmable has a lower priority atm, and I think I'm satisfied with the way it works right know (plus I don't have a clue if my project will become popular or not.. if it starts getting I'll definitely revisit it for improvements)

I do have one last question tho, if I may. My prim-water sends 3 different messages to 3 channels (mine, and the 2 swim huds) via 3 calls to RegionSayTo()... well 6 actually, 3 on collision_start() and 3 on collision_end(). Do I have to add a small llSleep(0.5) delay between each call?

 

Edited by hectic1
more info
Link to comment
Share on other sites

1 hour ago, animats said:

There's something called PrimSwim used by some swim HUDs which handles "are you in the water" for swim HUDs. Can you use that, and be compatible with existing swim HUDs?

I think you mean the Waterworks prim-water script, also creator of the following HUD (among other things):

https://marketplace.secondlife.com/p/The-Swimmer-206-from-Waterworks-Swim-in-prim-OR-sim-water/908729

In the description it says a lite version of that script is included with the HUD. I had searched for it (PrimSwim) before I post in the forum, couldn't find it. Probably it is not free, and as far as i know, not even available separately. Even if it was, I would need to check the code for its listening channel and its expected messages when ppl go in and out of their prim.

Or I could contact Waterworks, asking for that info. However, I had a look at the 1st review of the above mentioned HUD, dated in October 2018 saying that the hUD gives a ""Attachments cannot use llVolumeDetect" (hinting that they try to use llDetectVolume() inside the HUD script, which couldn't work anyway according to the Wiki). That, combined with the 2nd review which is a good one but dated back in 2017, made me think that probably that HUD and the PrimSwim script coming with it is probably either outdated or abandoned (and using llDetectVolume() too for detecting).

That's when I started looking for other alternatives, hopefully most recent ones. Plus I much prefer the HUDs to be free, since I'll be giving my prim-water free too.

I have already made my prim-water compatible with 2 free Swim HUDs (namely, AT-Swimmer and Thor's OAK HUD) and I'm totally happy with it. As i said, my main concern is that my prim-water works with my very own line of WetSense clothing (not released yet) and it seems to work fine so far. The free swim ability will be an extra bonus for pool owners (creators) who will be willing to use my prim-water.

PS. About my last question? Does anyone know? Should i insert a short delay between consecutive calls to llRegionSayto() or I'm fine w/o any delay between each call?

 

Edited by hectic1
Link to comment
Share on other sites

3 hours ago, hectic1 said:

Should i insert a short delay between consecutive calls to llRegionSayto() or I'm fine w/o any delay between each call?

 

No.  Not only is the delay unnecessary, it may mess up other things.  Unless you ever have a real need for using llSleep -- and there are plenty of good reasons to use it -- avoid it.  llSleep does exactly what it says.  It puts your entire script into sensory deprivation, so that it cannot respond to other triggers that you may want to be aware of.

  • Like 1
Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

No.  Not only is the delay unnecessary, it may mess up other things.  Unless you ever have a real need for using llSleep -- and there are plenty of good reasons to use it -- avoid it.  llSleep does exactly what it says.  It puts your entire script into sensory deprivation, so that it cannot respond to other triggers that you may want to be aware of.

Great! Million thanks once again! ♥

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1796 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...