Jump to content

How to open 2 doors when one is touched?


angeoco
 Share

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

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

Recommended Posts

This is my first effort at SL scripting. I found a script for opening and closing a door and would like to modify it to open/close two doors at the same time when one of them is touched. I was thinking along the lines of linking the two doors and including two "rotate" statements in the script, for the root prim and the other prim. I see the following code rotates a single door:

llSetLinkPrimitiveParamsFast(
  LINK_THIS,
  [
    PRIM_ROT_LOCAL,
    llEuler2Rot(<0, 0, LRot> * DEG_TO_RAD) * llGetLocalRot()
  ]
);

I have played around with the various constants and function calls in that code, but documentation seems sparse and the best result I can get is the two doors rotating together around the root prim's axis.

I'm sure there must be a simple solution, so any help would be appreciated. Thanks.

Link to comment
Share on other sites

Your instincts are good, but you need to send commands to the two doors separately, or at least with separate commands in the same function.  Assuming that your variable LRot is defined properly, changing it to -LRot for one of the doors will reverse that door's rotation.  So the trick is to write your llSetLinkPrimitiveParamsFast function a second time, addressing the other door's link number and using that reversed rotation.  That's the easy answer.

There are several extras in the answer, though.  One is that since you don;t necessarily know the link number of the other door, it's hard to address it properly.  You could solve that one by figuring out its number and using that in place of LINK_THIS, but if you ever do anything to the linkset. the number might change and your script would screw up. If you have only the two doors in the linkset, a better solution is to use LINK_ALL_CHILDREN or LINK_ALL_OTHERS to address it.  If there are more than two objects in the linkset, you'll have to take a more complicated route, name each link, and then determine its link number in the script.

Another "extra" is that if you put the script in one door, it should open both when someone touches either one, provided that you put the script in the root prim.  If not, it will only work in someone touches the door that has the script in it.

Finally, at least for now, it is possible to combine the two SLPPF commands into a single one, using the parameter PRIM_LINK_TARGET.  It's not truly necessary and won't make a perceptible difference in this case, but it's a slightly more sophisticated approach.

Incidentally, the classical way to open two doors simultaneously is to put identical scripts (with the LRot reversed) in both doors, not linked to each other, and have each one send a message to the other door in chat when it is touched.  You could still do that if you wanted to.

  • Like 2
Link to comment
Share on other sites

You need to send a signal to both doors telling them to open and close, and you need to give a bit of thought to how to make them simultaneously (or as near simultaneously as they can manage). 

Are the two doors linked together?   I ask because that makes a big difference to how to do it.   If they are, you can have both doors send a link message to both doors when one is  touched/collided with, and have them both open or close in response to the link message.   That's by far the visually most effective way to do it.   Otherwise if they're not linked you probably need to have the doors say "touched" (or something) to another prim -- not a door -- and have that receiver prim then say "Open" on a channel that both doors listen to, and have them open in the listen event.   That's because scripts can receive link messages that they themselves have sent, but they can't hear chat messages sent by a script in the same prim.

It's impossible to tell from the fragment you reproduce exactly what's causing the problem but it may be how you're defining LRot.   I don't know, though, since I would need to see the whole script.   I'm assuming it's in the door prim and that the door prim is a child prim.

There's quite a lot on doors and double doors in the Forum archives if you search.  I'm assuming you've take a look at the pinned thread https://community.secondlife.com/forums/topic/338230-options-for-scripting-doors/

  • Like 2
Link to comment
Share on other sites

Thanks to both of you for those replies! I had searched the forum library and archives and the sticky thread but didn't see anything obvious there.

However, your tips led me to Rolig's "Linkable Multiprim Sliding Door" script from 2011, which I adapted to suit rotating doors.

So here is the result:
 

integer DEBUG = FALSE;
key CLOSESOUND = "e7ff1054-003d-d134-66be-207573f2b535";
key OPENSOUND = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
float SOUNDVOL = 1.0;

integer opened = FALSE;

openorclose() {
    integer i;
    for (i=2;i<=llGetNumberOfPrims();++i) {
        string primname = llGetLinkName(i);
        vector r;
        if (primname == "upper door")
            if (opened) r = <0,0,90>; else r = <0,90,90>;
        if (primname == "lower door")
            if (opened) r = <0,0,90>; else r = <0,0,0>;
        llSetLinkPrimitiveParamsFast(
            i, [PRIM_ROT_LOCAL, llEuler2Rot(r * DEG_TO_RAD) * llGetLocalRot()]
        );
    }
    if (opened) {
        llTriggerSound(CLOSESOUND, SOUNDVOL);
        opened = FALSE;
        llSetTimerEvent(FALSE);
    } else {
        llTriggerSound(OPENSOUND, SOUNDVOL);
        opened = TRUE;
        llSetTimerEvent(30.0);
    }
}

default {
    touch_start(integer n) {
        string touchedprim =llGetLinkName(llDetectedLinkNumber(0));
        if (touchedprim != "upper door" && touchedprim != "lower door") return;
        if (DEBUG) {
            string s;
            if(opened) s = " closing"; else s = " opening";
            llSay(DEBUG_CHANNEL, s);
        }
        llResetTime();
        openorclose();
    }
    timer() { if (opened) openorclose(); }
}

 

Link to comment
Share on other sites

That works.  :)

You may want to include a failsafe to make it impossible to trigger touch_start if the doors are moving.  You may have already had that thought, since I see that you have llResetTime in the touch_start event and haven't used llGetTime anywhere yet.

  • Like 1
Link to comment
Share on other sites

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