User:Hidenori Glushenko/SmoothOpeningDoor

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

DoorInit

<lsl> /**

*    door-init.lsl
*    Released into the public domain by Hidenori Glushenko
*/

default {

   state_entry() {
       list params = llGetPrimitiveParams([PRIM_TYPE]);
       params = llListReplaceList(params,[<0.125,0.625,0.0>],2,2);
       llSetPrimitiveParams([PRIM_TYPE]+params+[PRIM_SIZE,<1.6,2.0,0.05>]);
       llRemoveInventory(llGetScriptName());        
   }    

}</lsl>


SmoothOpeningDoor

<lsl> /*-------------------------------------------------------------------

*  Smooth opening door script
*  This door opens toward the directrion opposit to the avatar's pos.
*  Released into the public domain by Hidenori Glushenko
*-------------------------------------------------------------------
*  Please initialise your prim's share using door_init.lsl
*-------------------------------------------------------------------
*/

rotation DOOR_ROT_ORG; // base rotation float DOOR_DIV_EULER = 150.0; // open angle float DOOR_OPEN_SEC = 10.0; // open time(seconds) float DOOR_MOVE_TARGET; integer TIMER_COUNT; integer TIMER_MAX = 40; // open speed

                                               //  larger is slower

/**

*  @state  default state : initialize prim's status
*/

default {

   state_entry() {
       llSetBuoyancy(1.0);
       llMinEventDelay( 0.01 );
       llSetStatus(STATUS_PHANTOM, FALSE);
       llSetStatus(STATUS_BLOCK_GRAB, TRUE);
       state   DoorClose;
   }

}

/**

*  @state  closed state
*/

state DoorClose {

   touch_start(integer total_number) {
       DOOR_ROT_ORG = llGetRot();

       //  check the touched avatar's position
       vector av_offset = (llDetectedPos(0)-llGetPos())/DOOR_ROT_ORG;
       float av_offset_z = av_offset.z;

       //  calculate the angle depend on the avatar's pos
       DOOR_MOVE_TARGET = (av_offset_z/llFabs(av_offset_z))
                           *DOOR_DIV_EULER;
       state DoorOpen;
   }

}

/**

*  @state  opening-opened-closing state
*/

state DoorOpen {

   state_entry() {
       TIMER_COUNT = 0;
       llSetTimerEvent(0.05);
       llSetStatus(STATUS_PHANTOM, TRUE);          //  set phantom
   }
   
   state_exit() {
       llSetStatus(STATUS_PHANTOM, FALSE);         //  set non-phantom when leaving this state
       llSetTimerEvent(0.0);
   }

   touch_start(integer total_number) {
       //  restart timer
       llSetTimerEvent(0.05);
   }

   timer() {
       rotation rot;
       ++TIMER_COUNT;                              //  count up

       //  If counter indicates starting door-close
       if (TIMER_COUNT == TIMER_MAX + 1) {
           llSetStatus(STATUS_PHANTOM, TRUE);      //  set phantom
           llSetTimerEvent(0.05);
       }

       //  calculate door-angle from counter
       float x = PI_BY_TWO*TIMER_COUNT/(float)TIMER_MAX;   //  calculate x(means the ratio)
       float new_rot_euler = DOOR_MOVE_TARGET * llPow(llSin(x), 2.0);  //  calculate angle
       llRotLookAt(rot = (llEuler2Rot(<0.0,new_rot_euler,0.0>
           *DEG_TO_RAD))*DOOR_ROT_ORG,1.0,1.0);    //  set door angle

       //  stop when opened
       if (TIMER_COUNT == TIMER_MAX) {
           //  switch timer to the 'open-time'
           llSetTimerEvent(DOOR_OPEN_SEC);
           llSleep(0.2);
           llSetStatus(STATUS_PHANTOM, FALSE);     //  set non-phantom when opened
           llSetStatus(STATUS_PHYSICS, TRUE);      //  force update rotation
           llSetStatus(STATUS_PHYSICS, FALSE);     //  force update rotation
           llSetRot(rot);

       //  go to close state when closed
       } else if (TIMER_COUNT >= (TIMER_MAX*2)) {
           llSleep(0.2);
           llSetStatus(STATUS_PHYSICS, TRUE);      //  force update rotation
           llSetStatus(STATUS_PHYSICS, FALSE);     //  force update rotation
           llSetRot(DOOR_ROT_ORG);
           state DoorClose;            
       }
   }

}</lsl>