Jump to content

Elevator AND Door LSL Question


Kipz Arado
 Share

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

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

Recommended Posts

I know an elevator and a door are two completely different things, but I have questions concerning two seperate scripts and thought I'd spare the forums some spam by making two individual threads. Anyways, I know to post on here a lot, but I've recently taken an extended break from Second Life, coming back to the game recently, I've decided to build a new house ground up with a friend of my mine. I've been looking to use some scripts that I have already created in the past so I wouldn't have to reinvent the wheel persay, and I've been having some problems getting them to work correctly.

To get onto the scripting, my first question will be about my "Home control device" This is a display that I setup on my home wall, and I can click buttons to lock / unlock doors, along with tint windows etc. Anyways, I used the freebie "Deluxe Door Script" and modified it to lock and unlock through linked messages when the HUD is touched. The door works perfectly fine when it's only linked to the hinge and door knobs / decorative prims attached to the door. However, when I link the door to my Home Control Display, only the hinge will rotate.When I asked how to fix this before I took my break previously, I was told to taper a simple prim door and it'll work with my script. I remember doing that, but I'm looking for a more complex door this time around, that's not a simple prim.

integer lock = 1;

// ********** SETTINGS HERE ************
float       TIMER       = 30.0;      // automatically close the door after this many seconds,
                                    // set to 0 to disable automatic closing

integer     DIRECTION   = 1;       // direction door opens in. Either 1 (outwards) or -1 (inwards);

float       VOLUME      = 0.8;      // sound volume, 1.0 loudest, 0.0 to disable sound
// ********** END OF SETTINGS **********


key         SOUND_OPEN  = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
key         SOUND_CLOSE = "e7ff1054-003d-d134-66be-207573f2b535";

vector      gPos;      // door position (objects move a tiny amount
                        // away from their position each time they are rotated,
                        // thus we need to workaround this by resetting
                        // the position after rotating)
                        
door(integer open) {
    if (open) {
        llTriggerSound(SOUND_OPEN, VOLUME);
        llSetLocalRot(llEuler2Rot(<0, 0, -DIRECTION * PI_BY_TWO>) * llGetLocalRot());
    } else { // close
        llSetLocalRot(llEuler2Rot(<0, 0, DIRECTION * PI_BY_TWO>) * llGetLocalRot());
        llTriggerSound(SOUND_CLOSE, VOLUME);
    }
}
        

default {   // first time startup
    state_entry() {
       
        gPos = llGetPos();  // remember where we're supposed to be
        door(TRUE);
        state closed;
    }
}
    
state closed {  // door is closed
    on_rez(integer start_param) {
        gPos = llGetPos();
    }

    state_entry() {
        door(FALSE);
    }
        
     link_message(integer sender_num, integer num, string str, key id)
   {
       if(llToLower(str) == "lock")
        {
            lock = 1;
        }
        if(llToLower(str) == "unlock")
        {
            lock = 0;
        }
    }

    touch_start(integer total_number) {
       
       if( lock == 1)
        {
        llSay(0,"This door is currently locked.");
    }
        else if (lock == 0)
        {
        state open;
    }
    }

    moving_end() {  // done moving me around, store new position
        gPos = llGetPos();
    }
}

state open {    // door is open
    on_rez(integer start_param) {
        gPos = llGetPos();
        state closed;
    }

    state_entry() {
        llSetTimerEvent(TIMER);
        llSetPos(gPos); // rotation drift workaround
        door(TRUE);
    }

link_message(integer sender_num, integer num, string str, key id)
   {
       if(llToLower(str) == "lock")
        {
            lock = 1;
        }
        if(llToLower(str) == "unlock")
        {
            lock = 0;
        }
    }
    
    touch_start(integer num) {
      
            
        state closed;
    }
    
    timer() { // auto-close
        state closed;
    }
    
    moving_start() { // close when being moved
        state closed;
    }
    
    state_exit() {
        llSetTimerEvent(0);
    }
}

 

That would be the door script.

This second script down below is my elevator script, well apart of it, and How i've scripted it would be I have a list, and the first number in the list is the first height, second number in list is second height, so on and so forth. When i make buttons labeled as 1,2,3,4 it goes to the corrisponding height. That would perfectly fine because the buttons would be attached to the elevator... I was wondering, how would I go about making a recall button.... because if I link the recall button to the elevator, they will move with it... lol

 touch_start(integer num_detected) {
        integer num = (integer) llGetLinkName(llDetectedLinkNumber(0));
        if(num != 0) {
            vector pos = llGetPos();
            if(llList2Float(floor_heights, num - 1) != 0) {
                stop();
                target_pos = <pos.x, pos.y, llList2Float(floor_heights, num - 1)>;
                target = llTarget(target_pos, .1);
                llSetStatus(STATUS_PHYSICS, TRUE);
                llMoveToTarget(target_pos, speed);
            }
        }
    }

 

I apologize in advance for the obnoxiously long wall of text, and flood of information. I have 2 seperate questions as I stated before, and would rather make 1 thread than 2. Thank you so much in advance for any help!!!!

 

Link to comment
Share on other sites

Actually it's probably good that you posted these together because they are quite closely related.  The problem is how root and child prims relate to each other in a build and what scripts can and can't do.

For your door: The "hinge" prim is the root so as that is moved and/or rotated everything else in the build moves with it.  Hence, all your "door knobs / decorative prims attached to the door" move as you expected.  As soon as you link the door to the Control Display (with the Display as the root) the hinge still moves because that's what has the script but the other prims are NOT "attached to the door" - they are attached to the Display now - so they don't move.  Unfortunately for you if you link the door to the Control Display but with the hinge as the root things will 'sort of' work - except that the Display will move in exactly the same way as the door knobs and other attached prims.  The only solution is to remember and move every single prim that needs to update.  There is a new-ish function that makes this easier but it may have sneaked past you as you've had an extended break: http://wiki.secondlife.com/wiki/LlSetLinkPrimitiveParamsFast)

Elevator: Has a similar problem in what is linked to the building and what is linked to the elevator.  Or, ultimately, exactly which prims have to move and which have to stay put.  As well as llSetLinkPrimitiveParamsFast() there is another simplification you can make in this case.  Rather than have a prim button for each floor in the lift you can have a single texture of the heights/floors the elevator can go to.  When a user touches this you can use http://wiki.secondlife.com/wiki/LlDetectedTouchST to calculate which part of the texture/prim they clicked on (eg; top, middle or bottom third if you've got a 3-storey building)

Link to comment
Share on other sites

For the elevator recall button, I think you need have the elevator listen on a known channel (I'd suggest using something like the examples here and generating a integer based on the owner's uuid plus something) and have the buttons speak on that channel.   If you simply name the button for the floor it's on, the elevator will pick that up in the listen event, and can then figure out where to go.   Use llRegionSay so you don't have to worry about the range and because it's less work for the sim (it doesn't have to calculate if the elevator is in earshot).

As to the door, if you're moving a multiple prim door, either you have to move the root prim of the unlinked door, as you're doing at the moment, or, if you link the door to the rest of the build, you'll have to move each component prim separately.   This is a lot easier than it used to be, since now you can use llSetLinkPrimitiveParamsFast to change PRIM_POS_LOCAL and PRIM_ROT_LOCAL for each part of the door.   If you use  PRIM_LINK_TARGET you can move all the component prims in the same call, which is as close to simultaneous as you'll get, but in my experience they're still likely to drift apart while the door's in motion (though obviously they'll all end up in the right place).

If you do it that way, you need to read PRIM_POS_LOCAL and PRIM_ROT_LOCAL for each component prim with the door in the open and closed positions and hard-code them into the script.   You'll also need to keep track of the link numbers -- I use meaningful names for integer variables, and loop through the script in state_entry  and if the links change, checking the prims' description fields to see what link number door1_handle might be. 

But, to my mind, it's a great deal of effort to achieve an effect that's never going to look as good as simply moving the whole door as a separate unlinked unit, so I'm always inclined to rez my doors in place, as separate objects, if they're of any complexity.   

 ETA -- Peter replied as I was writing.  I wouldn't use llSetLinkPrimitiveParamsFast for the elevator.  It's going to move very fast indeed, leaving -- on the way down -- the avatar standing in mid-air, like Wile E. Coyote in the RoadRunner cartoons when he's gone off a cliff, and, since it's not physical, I don't think it's going to move the avatar up, either.   You could sit the avatar on it, but then you're going to have to move the avatar as if he or she were another prim in the elevator.   You might want to play round with the new llSetKeyframedMotion, which is good for elevator platforms, but that will involve having the elevator as a separate object, set to PRIM_PHYSICS_SHAPE_CONVEX


Link to comment
Share on other sites

For the door...

Instead of flooding the object with scripts, if you want a more realistic looking door and still only want to use one script, try using a mesh door or even sculpted door which is a single object, with the pivot point (rotation point) on its side. Beware if you use mesh, the whole object will act like a mesh, concerning landimpact. This can have some unexpected results.

The llSetLinkPrimitiveParams(Fast) would also work ofcourse, but that requires a new script.

Link to comment
Share on other sites

Thank you guys for taking the time and efforts to post replies and help me out :). I've learned a lot and on my "quest" to become a better scripter I have been trying to do everything as "efficient" as I can get it. I've been scripting off and on since 06, and no matter what where, when, or what I was scripting, one thing i've always heard that I should be doing, is making the script as efficient as possible to cut down on sim lag and everything else. With that being said, that is why I approached my elevator script the way that I did, with linked message, and making sure if i name a prim a certain way, it will use a height from a list etc.. I also wanted to link the control to the door so it could use "unlock" and "lock" linked messages.

I did all of that in hopes that my scripts could use the least amount of listener script as possible, to once again, be efficient. I could have easily had all of my doors working by now by using a region listen or what ever the case may be to have the doors than rotate and what not. I will probably end up doing that, I was just wondering if there were really easily 1 or 2 line changes i could have made to my scripts to fix them. Like something I was over looking. I just didn't want to feel like a "noob" persay, by using llListen().

Once again, thank you guys for the replies!!

Link to comment
Share on other sites

Hmm, glad to hear you want to be efficient on script use:) ... but there's more to that than avoiding llListen.

You mentioned changing one or two lines in the script. As I understand it the script now uses llListen and you want to replace that. I think that's very possible, even when the parts aren't all linked. You could replace the chattery talk and listen with linked messages or llSetLinkedPrimitiveParams. If the prims aren't linked, use a very simple relay turning the command received by llListen into again llMessageLinked or llSetLinkedPrimitiveParams.

Link to comment
Share on other sites

  • 2 weeks later...

I've had a successful elevator script-set on the market for a few years (recently pulled to focus on something else). I've learned a lot from customer feedback and what not. The way I designed mine was to have the base of the elevator be the root prim, which contains the "elevator" script. Having the elevator base be the root puts it at floor level and allows for subsequent floor positional data to be acquired easily. The elevator script has a notecard that has relative height values for each floor (starting with floor 2), based on the first floor position, which is always where the elevator is when the script loads. I read in the floor position data into a list at elevator script start, then store the elevator's initial position (first floor). I then listen for buttons via link messages (the buttons in the elevator object) as well as external buttons via chat (call buttons, call floor plates). Each button is notecard configured with its floor number and a few other settings. The user key and and destination floor number are received by the elevator. If the user is valid, the destination offset referenced from the list and the elevator moves to the floor. To pack the elevator with a build you simply move it to the first floor and put it in a hold state so that it is waiting for touch. The next owner positions their build and touches the elevator to reset the script. The offsets are always right because they're based on the first floor position. Elevator doors are a little more tricky. Each door needs to know its floor number and have an option to ignore all other floors, this way they open on their assigned floor but not any other. The elevator needs to send out an arrival message when it arrives at a floor, to open the door. Hope this helps in your design.

Link to comment
Share on other sites

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