Jump to content
MIVIMEX

How to add a sensor to the door script?

Recommended Posts

Hello! Please help to combine these two scripts. I am trying to make a script for a linked door without a "hinge". I need to add the closing / opening sensor to the FIRST SCRIPT. Thank's for any help!

FIRST SCRIPT (please help to add sensor here)

// 2017 Maschinenwerk, Corp.
// All Rights Reserved. 

/*
 * Define the rotation in degrees, using the door prim's local coordinate
 * system
 */
vector      ROTATION            = <0.0, 0.0, 80.0>;
 
/*
 * Define the position of the virtual hinge; usually this is half the door
 * prim's width and thickness
 */
vector      HINGE_POSITION      = <-0.8, 0.05, 0.0>;
 
/*
 * Define how fast the door opens, in seconds
 */
float       SECONDS_TO_ROTATE   = 1.0;
 
/*
 * Define after how much time the door should close automatically, in seconds;
 * set to 0.0 to disable autolmatic closing
 */
float       AUTO_CLOSE_TIME     = 10.0;
 
/*
 * Define a sound that plays when the door starts to open; set to NULL_KEY
 * for no sound.
 */
key         SOUND_ON_OPEN       = "e5e01091-9c1f-4f8c-8486-46d560ff664f";
 
/*
 * Define a sound that plays when the door has closed; set to NULL_KEY
 * for no sound.
 */
key         SOUND_ON_CLOSE      = "88d13f1f-85a8-49da-99f7-6fa2781b2229";
 
/*
 * Define the volume of the opening and closing sounds
 */
float       SOUND_VOLUME        = 1.0;
 
/*
 * NORMALLY, THERE IS NO NEED TO CHANGE ANYTHING BELOW THIS COMMENT. IF YOU DO
 * YOU RISK BREAKING IT.
 */
 
integer     gClosed;            // Door state: TRUE = closed, FALSE = opened
rotation    gRotationClosed;    // Initial rotation of the door (closed)
vector      gPositionClosed;    // Initial position of the door (closed)
vector      gRotationPerSecond; // The amount to rotate each second
 
doOpenOrClose() {
    /*
     * Only perform the rotation if the door isn't root or unlinked
     */
    integer linkNumber = llGetLinkNumber();
    if (linkNumber < 2)
        return;
 
    if (gClosed) {
        /*
         * Store the initial rotation and position so we can return to it.
         *
         * Rotating back purely by calculations can in the longer term cause the door
         * to be positioned incorrectly because of precision errors
         *
         * We determine this everytime before the door is being opened in case it was
         * moved, assuming the door was closed whilst being manipulated.
         */
        gPositionClosed = llGetLocalPos();
        gRotationClosed = llGetLocalRot();
 
        /*
         * Play the opening sound and preload the closing sound
         */
        if (SOUND_ON_OPEN)
            llPlaySound(SOUND_ON_OPEN, SOUND_VOLUME);
    }
 
    vector hingePosition = gPositionClosed + HINGE_POSITION * gRotationClosed;
 
    /*
     * Reset the timer and start moving
     */
    llResetTime();
    while (llGetTime() < SECONDS_TO_ROTATE) {
        float time = llGetTime();
        if (! gClosed)
            /*
             * Invert the timer for closing direction
             */
            time = SECONDS_TO_ROTATE - time;
 
        rotation rotationThisStep = llEuler2Rot(gRotationPerSecond * time) * gRotationClosed;
        vector positionThisStep = hingePosition - HINGE_POSITION * rotationThisStep;
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationThisStep, PRIM_POS_LOCAL, positionThisStep]);
    }
 
    /*
     * Set the new state
     */
    gClosed = !gClosed;
 
    if (gClosed) {
        /*
         * Finalize the closing movement
         */
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, gRotationClosed, PRIM_POS_LOCAL, gPositionClosed]);
 
        /*
         * Play the closing sound and preload the opening sound
         */
        if (SOUND_ON_CLOSE)
            llPlaySound(SOUND_ON_CLOSE, SOUND_VOLUME);
        if (SOUND_ON_OPEN)
            llPreloadSound(SOUND_ON_OPEN);
    } else {
        /*
         * Finalize the opening movement
         */
        rotation rotationOpened = llEuler2Rot(ROTATION * DEG_TO_RAD) * gRotationClosed;
        vector positionOpened = hingePosition - HINGE_POSITION * rotationOpened;
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationOpened, PRIM_POS_LOCAL, positionOpened]);
 
        /*
         * Preload the closing sound
         */
        if (SOUND_ON_CLOSE)
            llPreloadSound(SOUND_ON_CLOSE);
 
        /*
         * Set a timer to automatically close
         */
        llSetTimerEvent(AUTO_CLOSE_TIME);
    }
}
 
default {
    state_entry() {
        /*
         * Assume the door is closed when the script is reset
         */
        gClosed = TRUE;
 
        /*
         * These doesn't change unless the script is changed, calculate them once
         */
        gRotationPerSecond = (ROTATION * DEG_TO_RAD / SECONDS_TO_ROTATE);
 
        /*
         * Preload the opening sound
         */
        if (SOUND_ON_OPEN)
            llPreloadSound(SOUND_ON_OPEN);
    }
    touch_start(integer agentCount) {
        doOpenOrClose();
    }
    timer() {
        llSetTimerEvent(0.0);
 
        /*
         * Close the door if it isn't already closed
         */
        if (! gClosed)
            doOpenOrClose();
    }
}

SECOND SCRIPT (sensor is here)

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

integer DOOR_OPEN = 1;
integer DOOR_CLOSE = 2;

vector originalPos;

door(integer what) {
    rotation rot;
    rotation delta;
    vector eul;

    llSetTimerEvent(0);

    if (what == DOOR_OPEN) {
        //        llTriggerSound("doorOpen", 1);  
        eul = < 0, 0, 90 * DIRECTION > ; //90 degrees around the z-axis, in Euler form 

    } else if (what == DOOR_CLOSE) {
        //        llTriggerSound("doorClose", 1);  
        eul = < 0, 0, 90 * -DIRECTION > ; //90 degrees around the z-axis, in Euler form
    }

    eul *= DEG_TO_RAD; //convert to radians rotation
    rot = llGetRot();
    delta = llEuler2Rot(eul);
    rot = delta * rot;
    llSetRot(rot);
}


default {
    on_rez(integer start_param) {
        llResetScript();
    }

    state_entry() {
        originalPos = llGetPos();
        llSensorRepeat("", "", AGENT, 5, PI, 1);
    }

    sensor(integer num_detected) {
        door(DOOR_OPEN);
        state open_state;
    }

    moving_end() {
        originalPos = llGetPos();
    }
}

state open_state {
    state_entry() {
        llSensorRepeat("", "", AGENT, 5, PI, 1);
    }

    no_sensor() {
        door(DOOR_CLOSE);
        llSetPos(originalPos);
        state
        default;
    }

    sensor(integer num_detected) {}


    moving_start() {
        door(DOOR_CLOSE);
        state
        default;
    }
}

 

Edited by MIVIMEX

Share this post


Link to post
Share on other sites

Just replace the touch_start event with the sensor event and start the repeating sensor in the state_entry event. I would advise against doing that, personally, however.  It's not only potentially adding lag to your region, but you'll get exactly the same effect by replacing the touch_start event with a collision_start event. Then you can decide whether to make the door itself the collision sensor (in which case, you'll need to modify the script just slightly to make it swing away from the person who collides with it) or to make an independent sensor (in which case you'll need to modify things to make the sensor communicate with the door).  Either way, the smartest move would be to write your own script instead of trying to glue two of someone else's scripts together.  I suggest spending some time digesting the ideas in this sticky thread >>> 

 

  • Thanks 1

Share this post


Link to post
Share on other sites
44 minutes ago, Rolig Loon said:

 you'll get exactly the same effect by replacing the touch_start event with a collision_start event. Then you can decide whether to make the door itself the collision sensor (in which case, you'll need to modify the script just slightly to make it swing away from the person who collides with it)

Thank you very much for your reply!

I replaced the sensor with a collision event. It works perfectly!

Could you tell me how to make the door open in the opposite direction from the avatar, please?

And is there anything extra that can be removed after I added a collision event?

Thanks! You already helped me a lot!

vector ROTATION = < 0.0, 0.0, 80.0 > ;
vector HINGE_POSITION = < -0.8, 0.05, 0.0 > ;
float SECONDS_TO_ROTATE = 1.0;
float AUTO_CLOSE_TIME = 2.0;
key SOUND_ON_OPEN = "e5e01091-9c1f-4f8c-8486-46d560ff664f";
key SOUND_ON_CLOSE = "88d13f1f-85a8-49da-99f7-6fa2781b2229";
float SOUND_VOLUME = 1.0;
integer gClosed;
rotation gRotationClosed;
vector gPositionClosed;
vector gRotationPerSecond;

doOpenOrClose() {

    integer linkNumber = llGetLinkNumber();
    if (linkNumber < 2)
        return;

    if (gClosed) {

        gPositionClosed = llGetLocalPos();
        gRotationClosed = llGetLocalRot();


        if (SOUND_ON_OPEN)
            llPlaySound(SOUND_ON_OPEN, SOUND_VOLUME);
    }

    vector hingePosition = gPositionClosed + HINGE_POSITION * gRotationClosed;


    llResetTime();
    while (llGetTime() < SECONDS_TO_ROTATE) {
        float time = llGetTime();
        if (!gClosed)

            time = SECONDS_TO_ROTATE - time;

        rotation rotationThisStep = llEuler2Rot(gRotationPerSecond * time) * gRotationClosed;
        vector positionThisStep = hingePosition - HINGE_POSITION * rotationThisStep;
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationThisStep, PRIM_POS_LOCAL, positionThisStep]);
    }

    gClosed = !gClosed;

    if (gClosed) {

        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, gRotationClosed, PRIM_POS_LOCAL, gPositionClosed]);


        if (SOUND_ON_CLOSE)
            llPlaySound(SOUND_ON_CLOSE, SOUND_VOLUME);
        if (SOUND_ON_OPEN)
            llPreloadSound(SOUND_ON_OPEN);
    } else {

        rotation rotationOpened = llEuler2Rot(ROTATION * DEG_TO_RAD) * gRotationClosed;
        vector positionOpened = hingePosition - HINGE_POSITION * rotationOpened;
        llSetLinkPrimitiveParamsFast(linkNumber, [PRIM_ROT_LOCAL, rotationOpened, PRIM_POS_LOCAL, positionOpened]);


        if (SOUND_ON_CLOSE)
            llPreloadSound(SOUND_ON_CLOSE);


        llSetTimerEvent(AUTO_CLOSE_TIME);
    }
}

default {
    state_entry() {


        gClosed = TRUE;


        gRotationPerSecond = (ROTATION * DEG_TO_RAD / SECONDS_TO_ROTATE);

        if (SOUND_ON_OPEN)
            llPreloadSound(SOUND_ON_OPEN);
    }
    collision_start(integer num) {
        doOpenOrClose();
    }
    timer() {
        llSetTimerEvent(0.0);


        if (!gClosed)
            doOpenOrClose();
    }
}

 

Share this post


Link to post
Share on other sites

There are several ideas in 

I like the version that Ruthven added to that thread.

The best script, though, is the one that you write for yourself.  Only then will you truly understand its logic.  ;)

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
25 minutes ago, Rolig Loon said:

There are several ideas in 

I like the version that Ruthven added to that thread.

The best script, though, is the one that you write for yourself.  Only then will you truly understand its logic.  ;)

Thank you very much! did I understand correctly that the door with the hinge is being discussed in this topic?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×