Jump to content

Hot tubs, scripted water, and rezz boxes.


AnthonyMann
 Share

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

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

Recommended Posts

I just made a really nice build that includes two hot tubs. The hot tub scripts are on two different channels. It was all packed up into a Casper Rezz-Free box. The entire build rezzes properly, with each peice rezzing over the rezz-free box and then moving into position. The problem is that the water from the hot tubs stays over the box and doesn't move to the hot tubs.

The water prim itself is inside the hot tub, and rezzes when the tub rezzes (but then the water stays behind when the tub moves into it's position in the build).

The question...in the hot tub script is


Init_Water()                                    // To Rez Water or to Reset it
{
    llSay(WATER_CHANNEL,"WATER DIE");           // Kill any Water we have running
    
    WATER_POS = llGetPos();                     // Fetch the tubs coords and calculate
    WATER_POS.z = WATER_POS.z + .01;            // Water start position and rotation
    WATER_ROT = llGetRot();  
                                                // Finally, rez the water    
    llRezObject(WATER_NAME, WATER_POS, ZERO_VECTOR, WATER_ROT, 0);  
}

 

so, if I read this right, this kills any 'water' prims around, then rezzes a new one based on the tubs position.

is there any way to delay this rezzing of the water until after the tub moves into position? say about 3 seconds?

 

Thanks for any help, I'm no scripter, that's for sure :)

Link to comment
Share on other sites

The way I would do it is, at the point in the script where init_Water() is called, I would insert a timer event, and then call init_Water in that.

So, for example, 

Init_Water()                                    // To Rez Water or to Reset it{	llSay(WATER_CHANNEL,"WATER DIE");           // Kill any Water we have running	WATER_POS = llGetPos();                     // Fetch the tubs coords and calculate	WATER_POS.z = WATER_POS.z + .01;            // Water start position and rotation	WATER_ROT = llGetRot();	// Finally, rez the water	llRezObject(WATER_NAME, WATER_POS, ZERO_VECTOR, WATER_ROT, 0);}default{	on_rez(integer start_param)	{		// do stuff		llSetTimerEvent(3.0);			}	timer()	{		Init_Water();		llSetTimerEvent(0.0);	}}

 

You might be tempted to use llSleep() instead of a timer.   That's not a good idea, to my mind, for something like this.  It's a really bad habit to get into -- it can make all sorts of things go wrong, if you're not very careful.   

Link to comment
Share on other sites

There are surely ways around this, but without seeing more of the code, I'm not too sure you want to make the change in this Init_Water() function itself. If Init_Water is called in the on_rez event, then you could add "llSleep(3.0);" just before that call.

(If that's the only place it's called, then it would be okay to instead put the llSleep inside the function, but if it's called elsewhere, you probably don't want to delay the other calls.)

If the script doesn't contain an on_rez section or if Init_Water isn't called there, I think it best if we saw everywhere it is called.

[ETA: Without seeing the rest of the code, the llSleep() seems to me safer to suggest than a timer() event. If there's no timer already, it would be fine to introduce one, but if there is, we'd have to introduce a global flag to conditionalize the timer code. I'm thinking the script doesn't need to do anything else while it's rezzing the water for the first time, so sleeping should be fine.]

[ETA 2: I'm understanding the problem to be that the water gets rezzed automatically when the tub is rezzed, and that this is the desired behavior. Now that I think about it, though, this is going to be a problem not just when first rezzing but also when the user moves the rezzer-controlled build, because the water prim isn't going to have the rezzer's positioning script inside. Would it be a huge problem if the tubs rezzed empty, and only filled during the user's normal operation of the tub?]

Link to comment
Share on other sites

Depending on what the rest of the script looks like, one way to do it would be to put a llSetTimerEvent(3.0); statement in your init() function and then move everything except the llSay statement to a new timer event.  Unless you already have a timer event in that state, doing that should get you the 3 second delay you want.  If I understand your problem, though, rezzing isn't the issue.  You seem to be concerned because the old water prim isn't vanishing -- not because a new one isn't rezzing.  It would seem smarter to change the llSay statement to llRegionSay, so that the DIE message can be heard from more than 20m away.  Unless I am misunderstanding the problem ......

Link to comment
Share on other sites


AnthonyMann wrote:

Could I put the timer event at the beginning of the entire script, so that no water was killed or rezzed for 3 seconds? I think if the tub moved into it's position and did nothing for 3 seconds it would fix my problem.

It doesn't matter where you put the timer event.   The important thing is where you call llSetTimerEvent(3.0);   -- in English, that means something like "book an alarm call in 3.0 seconds' time".   Then when the timer event fires, it executes the instructions in the timer(){  } event.

So what my script does is, pretty much, what you want it to.   That is, first thing after the prim is rezzed, it sets a timer event to go off in 3 seconds, and then, when that happens, 3 seconds later, it rezzes the water and stops the timer.

What Qie is suggesting is something like

Init_Water()                                    // To Rez Water or to Reset it{	llSay(WATER_CHANNEL,"WATER DIE");           // Kill any Water we have running	WATER_POS = llGetPos();                     // Fetch the tubs coords and calculate	WATER_POS.z = WATER_POS.z + .01;            // Water start position and rotation	WATER_ROT = llGetRot();	// Finally, rez the water	llRezObject(WATER_NAME, WATER_POS, ZERO_VECTOR, WATER_ROT, 0);}default{	on_rez(integer start_param)	{		llSleep(3.0);		Init_Water();	}}

 That just means "When the prim is rezzed, sleep the script and don't do anything for 3 seconds, and then rez the water".

Qie's right -- there's nothing wrong with doing that way rather than the way I suggested (in fact, all things being equal, I'd do it Qie's way too).  

The reason I warned against it, though, is that there are some circumstances when using llSleep as a quick and easy substitute for a timer event is a really bad idea, and I don't want to encourage a beginning scripter to  think it's a good alternative most of the time, because it can sometimes make things go badly wrong in ways you're not expecting.

  • Like 1
Link to comment
Share on other sites


AnthonyMann wrote:

Actually, it would be great if the tub rezzed empty and only rezzed the water after the tub was 'put into use' , long after the build was moved/ set/ and rezzer scripts removed.

Right, so I'm thinking the on_rez event must be what calls this Init_Water() function. If that's right, I'd just remove or comment out that function call from the on_rez section of the script. (Hmm. Actually, the call might be in state_entry() instead of on_rez, and the same thing should work. This is all kind of guessing what the script must be like, including an assumption that some regular user operation also rezzes the water prim to "fill the tub" or something of the sort.)

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4161 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...