Difference between revisions of "One Script, many doors"
m |
(corrected again the mask from 1FFF to FFF) |
||
(6 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
This script is my attempt at solving the massive amount of simple door scripts one can have in a sim (I removed about 110 door scripts in my sim using this system) | This script is my attempt at solving the massive amount of simple door scripts one can have in a sim (I removed about 110 door scripts in my sim using this system) | ||
It handles clockwise and counter clockwise door direction, a name based access control list, play sounds, and the root prim | It handles clockwise and counter clockwise door direction, a name-based access control list, play sounds, and the root prim reports memory free (useful for REALLY big door sets). | ||
HOW TO USE IT | HOW TO USE IT | ||
Line 12: | Line 12: | ||
* All the doors must have "left" or "right" in their description depending on the direction you want them to swing to. | * All the doors must have "left" or "right" in their description depending on the direction you want them to swing to. | ||
* In the root prim you will need 3 rezzable objects (simple cubes will do) named "open" , "close" and "lock" with, in them, the corresponding scripts (see at the bottom of the page) in order to play sounds at the right place. | * In the root prim you will need 3 rezzable objects (simple cubes will do) named "open" , "close" and "lock" with, in them, the corresponding scripts (see at the bottom of the page) in order to play sounds at the right place. | ||
* You need a configuration notecard called "config" | * You need a configuration notecard called "config" | ||
main door script: must be in the root prim of the door link set. | main door script: must be in the root prim of the door link set. | ||
< | <source lang="lsl2"> | ||
/******************************************* | /******************************************* | ||
Single script, linked, lockable, door system | Single script, linked, lockable, door system | ||
Line 32: | Line 32: | ||
//This functions is from Nomad Padar, pretty awesome! | //This functions is from Nomad Padar, pretty awesome! | ||
//encode from vector to integer | //encode from vector to integer | ||
integer vec2int(vector v) | integer vec2int(vector v) | ||
{ | { | ||
integer x = (integer)(v.x); | integer x = (integer)(v.x); | ||
Line 38: | Line 38: | ||
integer z = (integer)(v.z); | integer z = (integer)(v.z); | ||
integer out; | integer out; | ||
//Rounds to 0, .5, or 1.0 | //Rounds to 0, .5, or 1.0 | ||
float delta = v.x-x; | float delta = v.x-x; | ||
if((delta>.25) && (delta<.75)) | if((delta>.25) && (delta<.75)) | ||
out += 0x10000000; | |||
else if(delta>.75) | else if(delta>.75) | ||
out += 0x1; | |||
delta = v.y-y; | delta = v.y-y; | ||
if((delta>.25) && (delta<.75)) | if((delta>.25) && (delta<.75)) | ||
out += 0x20000000; | |||
else if(delta>.75) | else if(delta>.75) | ||
out += 0x100; | |||
delta = v.z-z; | delta = v.z-z; | ||
if((delta>.25) && (delta<.75)) | if((delta>.25) && (delta<.75)) | ||
out += 0x40000000; | |||
else if(delta>.75) | else if(delta>.75) | ||
out += 0x10000; | |||
out += x+(y<<8)+(z<<16); | out += x+(y<<8)+(z<<16); | ||
return out; | return out; | ||
} | } | ||
list door_names | list door_names = [];//door list | ||
list door_num | list door_num = [];//corresponding link numbers | ||
list door_closed_rot = [];//corresponding closed state rotation | list door_closed_rot = [];//corresponding closed state rotation | ||
list door_direction | list door_direction = [];//which direction the door spin open | ||
list door_open | list door_open = [];//is the door open? | ||
list door_open_time | list door_open_time = [];//when was it open? | ||
list door_acl | list door_acl = [];//who can open the door (by user id) | ||
list door_pos | list door_pos = [];//the position of the door | ||
list user_indexes | list user_indexes = [];//list of users (user ids) | ||
integer is_active = FALSE;//if this is false the script ignore touches | integer is_active = FALSE;//if this is false the script ignore touches | ||
Line 80: | Line 80: | ||
recount_doors() | recount_doors() | ||
{ | { | ||
//this function recount the doors and record all the different door characteristics | |||
//only ran after script reset/when an object is linked/unlinked | |||
is_active = FALSE; | |||
llSetText("recounting doors...",<1.0,1.0,1.0>,1.0); | |||
integer prims = llGetNumberOfPrims(); | |||
integer i; | |||
for(i=2;i<=prims;i++) | |||
{ | |||
key prim = llGetLinkKey(i); | |||
list tmp = llGetObjectDetails(prim,[OBJECT_NAME,OBJECT_DESC,OBJECT_ROT,OBJECT_POS]); | |||
string prim_name = llList2String(tmp,0); | |||
string prim_descr = llList2String(tmp,1); | |||
rotation prim_rot = (rotation)llList2String(tmp,2); | |||
vector prim_pos = (vector)llList2String(tmp,3); | |||
door_num += [i]; | |||
door_names += [prim_name]; | |||
door_closed_rot += [prim_rot]; | |||
door_open += [FALSE]; | |||
door_open_time += [0]; | |||
if(prim_descr == "right") | |||
door_direction += [TRUE]; | |||
else | |||
door_direction += [FALSE]; | |||
door_acl += [""]; | |||
door_pos += [prim_pos]; | |||
} | |||
llSetText("...done!",<1,1,1>,1.0); | |||
reload_acl(); | |||
} | } | ||
Line 119: | Line 119: | ||
reload_acl() | reload_acl() | ||
{ | { | ||
llSetText("reloading access controls...",<1,1,1>,1.0); | |||
is_active = FALSE; | |||
nLine = 0; | |||
//remove all acl | |||
integer i; | |||
for(i=0;i<llGetListLength(door_num);i++) | |||
door_acl = llListReplaceList(door_acl,[""],i,i); | |||
user_indexes = []; | |||
llGetNotecardLine(config,nLine); | |||
} | } | ||
Line 135: | Line 135: | ||
close(integer index) | close(integer index) | ||
{ | { | ||
integer linknum = llList2Integer(door_num,index); | |||
rotation closed = llList2Rot(door_closed_rot,index); | |||
llSetLinkPrimitiveParams(linknum,[PRIM_ROTATION,closed]); | |||
door_open = llListReplaceList(door_open,[FALSE],index,index); | |||
} | } | ||
//close a door (by index) using the stored rotation and adding or substracting 90 degrees | //close a door (by index) using the stored rotation and adding or substracting 90 degrees | ||
//on the Z world axis depending of the direction recorded for the door. | //on the Z world axis depending of the direction recorded for the door. | ||
//also record it's opening time (unix timestamp) | //also record it's opening time (unix timestamp) | ||
open(integer index) | open(integer index) | ||
{ | { | ||
integer linknum = llList2Integer(door_num,index); | |||
rotation closed = llList2Rot(door_closed_rot,index); | |||
rotation open; | |||
if( llList2Integer(door_direction,index) ) | |||
open = llEuler2Rot(llRot2Euler(closed)+ (<0,0,90> *DEG_TO_RAD)); | |||
else | |||
open = llEuler2Rot(llRot2Euler(closed)+ (<0,0,-90> *DEG_TO_RAD)); | |||
llSetLinkPrimitiveParams(linknum,[PRIM_ROTATION,open]); | |||
door_open_time = llListReplaceList(door_open_time,[llGetUnixTime()],index,index); | |||
door_open = llListReplaceList(door_open,[TRUE],index,index); | |||
llSetTimerEvent(1.0); | |||
} | } | ||
Line 166: | Line 166: | ||
play_open(vector pos) | play_open(vector pos) | ||
{ | { | ||
llRezObject("open",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(pos)); | |||
} | } | ||
play_close(vector pos) | play_close(vector pos) | ||
{ | { | ||
llRezObject("close",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(pos)); | |||
} | } | ||
play_lock(vector pos) | play_lock(vector pos) | ||
{ | { | ||
llRezObject("lock",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(pos)); | |||
} | } | ||
Line 182: | Line 182: | ||
touch_start(integer total_number) | touch_start(integer total_number) | ||
{ | { | ||
integer userid; | |||
if(!is_active) | |||
return; | |||
//considering we MAY receive more than one touch at the same time since | |||
//we can manage many doors. | |||
for(userid=0;userid<total_number;userid++) | |||
{ | |||
integer door_id = llDetectedLinkNumber(userid); | |||
string clicker_name = llDetectedName(userid); | |||
integer door_index = llListFindList(door_num,[door_id]); | |||
if(door_index == -1) | |||
return;//unknown door? do nothing | |||
integer is_open = llList2Integer(door_open,door_index); | |||
vector door_vec = llList2Vector(door_pos,door_index); | |||
//we do not accept touches that are further away from activation_distance | |||
if( llVecDist(door_vec,llDetectedPos(userid) )> activation_distance ) | |||
llInstantMessage(llDetectedKey(userid),"You can't use this from this distance."); | |||
else | |||
{ | |||
if(is_open) | |||
{ //if the door is open, simply play sound and close it. | |||
play_close(door_vec); | |||
close(door_index); | |||
} | |||
else | |||
{ | |||
string acl_string = llList2String(door_acl,door_index); | |||
//if the acl string is empty for this door we simply open it | |||
if(acl_string == "") //no specific locking | |||
{ | |||
play_open(door_vec); | |||
open(door_index); | |||
} | |||
else | |||
{ | |||
//otherwise we lookup if the userid that correspond to the person who touched | |||
//the door match any of the ones in the ACL string | |||
integer user_index = llListFindList(user_indexes,[clicker_name]); | |||
if(user_index == -1) //we don't even know this user? sure as hell there is no acl about him | |||
play_lock(door_vec); | |||
else | |||
{ | |||
list acl_list = llParseString2List(acl_string,[","],[]); | |||
if(llListFindList(acl_list,[(string)user_index]) != -1) | |||
{ | |||
play_open(door_vec); | |||
open(door_index); | |||
} | |||
else | |||
play_lock(door_vec); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | } | ||
dataserver(key id,string data) | dataserver(key id,string data) | ||
{ | { | ||
//notecard reading stuff | |||
if(data != EOF) | |||
{ | |||
if(data != "" && data != " " && llGetSubString(data,0,1) != "//") | |||
{ | |||
list command_and_data = llParseString2List(data,["="],[]); | |||
string door_name = llList2String(command_and_data,0); | |||
string user_names_string = llList2String(command_and_data,1); | |||
integer index = llListFindList(door_names,[door_name]); | |||
if(index != -1) | |||
{ | |||
list user_names_list = llParseString2List(user_names_string,[","],[]); | |||
integer j; | |||
list pre_acl_list; | |||
for(j=0;j<llGetListLength(user_names_list);j++) | |||
{ | |||
string user_name = llList2String(user_names_list,j); | |||
integer index2 = llListFindList(user_indexes,[user_name]); | |||
if( index2 == -1) | |||
{ | |||
pre_acl_list += llGetListLength(user_indexes); | |||
user_indexes += [user_name]; | |||
} | |||
else | |||
pre_acl_list += [index2]; | |||
} | |||
string pre_acl_string = llDumpList2String(pre_acl_list,","); | |||
door_acl = llListReplaceList(door_acl,[pre_acl_string],index,index); | |||
} | |||
} | |||
nLine++; | |||
llGetNotecardLine(config,nLine); | |||
} | |||
else | |||
{ | |||
is_active = TRUE; | |||
llOwnerSay("config reloaded"); | |||
llSetText((string)llGetFreeMemory()+"bits free",<.5,.5,.5>,.5); | |||
} | |||
} | } | ||
state_entry() | state_entry() | ||
{ | { | ||
recount_doors(); | |||
} | } | ||
changed(integer change) | changed(integer change) | ||
{ | { | ||
//if we detect an inventory change we reread the notecard | |||
//if we detect a linkchange we reset the script and recount doors first | |||
if( (change & CHANGED_INVENTORY) == CHANGED_INVENTORY) | |||
reload_acl(); | |||
if( (change & CHANGED_LINK) == CHANGED_LINK) | |||
llResetScript(); | |||
} | } | ||
timer() | timer() | ||
{ | { | ||
//timer will run once a second as long as at least one door is open. | |||
if(llListFindList(door_open,[TRUE]) == -1) | |||
{ | |||
llSetTimerEvent(0.0); | |||
return; | |||
} | |||
integer i; | |||
//each run of the timer we loop through the timestamps to check if one of them is too old | |||
//(which means we can force close the associated door | |||
for(i=0;i<llGetListLength(door_open_time);i++) | |||
{ | |||
integer is_open = llList2Integer(door_open,i); | |||
integer time = llList2Integer(door_open_time,i); | |||
if( is_open && ((time + autoclose_time) < llGetUnixTime())) | |||
{ | |||
vector door_vec = llList2Vector(door_pos,i); | |||
llRezObject("close",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(door_vec)); | |||
close(i); | |||
} | |||
} | |||
} | } | ||
} | } | ||
</ | </source> | ||
Sound emitter script | Sound emitter script | ||
Line 335: | Line 335: | ||
You need this script in the 3 rezzable objects "open" "close" and "lock" in order to play your door sounds at the right place (At the time i wrote this , lsl doesn't allow yet to play sounds from an unscripted prim in a link set) | You need this script in the 3 rezzable objects "open" "close" and "lock" in order to play your door sounds at the right place (At the time i wrote this , lsl doesn't allow yet to play sounds from an unscripted prim in a link set) | ||
< | <source lang="lsl2"> | ||
string sound_to_play = "my door sound";// put your sound name/key here | string sound_to_play = "my door sound";// put your sound name/key here | ||
//This functions is from Nomad Padar, pretty awesome! | //This functions is from Nomad Padar, pretty awesome! | ||
//decode from integer to vector | //decode from integer to vector | ||
vector int2vec(integer n) | vector int2vec(integer n) | ||
{ | { | ||
//0zyx ZZZZ ZZZZ ZZZZ YYYY YYYY XXXX XXXX | //0zyx ZZZZ ZZZZ ZZZZ YYYY YYYY XXXX XXXX | ||
return <n&0xFF, (n>>8)&0xFF, ((n>>16)& | return <n&0xFF, (n>>8)&0xFF, ((n>>16)&0xFFF)> + <((n&0x10000000)!=0)*.5,((n&0x20000000)!=0)*.5,((n&0x40000000)!=0)*.5>; | ||
} | } | ||
default | default | ||
{ | { | ||
state_entry() | state_entry() | ||
Line 356: | Line 356: | ||
on_rez(integer a) | on_rez(integer a) | ||
{ | { | ||
if(a == 0) | |||
return; | |||
vector destination = int2vec(a); | |||
integer i; | |||
for(i=0 ; i<50 && (llGetPos() != destination) ; i++) | |||
llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, destination]); | |||
if(llGetPos() == destination) | |||
llTriggerSound(sound_to_play,1.0); | |||
llDie(); | |||
} | } | ||
} | } | ||
</ | </source> | ||
Example "config" notecard: | Example "config" notecard: | ||
//lines starting with "//" are ignored | //lines starting with "//" are ignored | ||
//Syntax: one line per door in the format door_name=user name,user name | //Syntax: one line per door in the format door_name=user name,user name | ||
My fancy front door=Kyrah Abattoir | My fancy front door=Kyrah Abattoir | ||
My secret playroom door=Kyrah Abattoir,Timeless Prototype | My secret playroom door=Kyrah Abattoir,Timeless Prototype | ||
//of course if you want to lock a door from anybody you can set it to something like this: | //of course if you want to lock a door from anybody you can set it to something like this: | ||
Mine entrance=condemned until further notice | Mine entrance=condemned until further notice | ||
--[[User:Kyrah Abattoir|Kyrah Abattoir]] 18:46, 7 March 2010 (UTC) | --[[User:Kyrah Abattoir|Kyrah Abattoir]] 18:46, 7 March 2010 (UTC) |
Latest revision as of 08:25, 28 September 2015
This script is my attempt at solving the massive amount of simple door scripts one can have in a sim (I removed about 110 door scripts in my sim using this system)
It handles clockwise and counter clockwise door direction, a name-based access control list, play sounds, and the root prim reports memory free (useful for REALLY big door sets).
HOW TO USE IT
All your doors have to be one prim, typical cube with a path cut of 0.125 0.625 .
- All your doors must be linked to a root prim which won't be a door.
- All the doors must be uniquely named.
- All the doors must have "left" or "right" in their description depending on the direction you want them to swing to.
- In the root prim you will need 3 rezzable objects (simple cubes will do) named "open" , "close" and "lock" with, in them, the corresponding scripts (see at the bottom of the page) in order to play sounds at the right place.
- You need a configuration notecard called "config"
main door script: must be in the root prim of the door link set.
/*******************************************
Single script, linked, lockable, door system
by Kyrah Abattoir
allow you to control many doors from a single
core script, complete with sound projectors
and name based access control!
*******************************************/
float autoclose_time = 30.0;//define how long the script will wait before closing a door.
float activation_distance = 2.0;//define how long the script will wait before closing a door.
//This functions is from Nomad Padar, pretty awesome!
//encode from vector to integer
integer vec2int(vector v)
{
integer x = (integer)(v.x);
integer y = (integer)(v.y);
integer z = (integer)(v.z);
integer out;
//Rounds to 0, .5, or 1.0
float delta = v.x-x;
if((delta>.25) && (delta<.75))
out += 0x10000000;
else if(delta>.75)
out += 0x1;
delta = v.y-y;
if((delta>.25) && (delta<.75))
out += 0x20000000;
else if(delta>.75)
out += 0x100;
delta = v.z-z;
if((delta>.25) && (delta<.75))
out += 0x40000000;
else if(delta>.75)
out += 0x10000;
out += x+(y<<8)+(z<<16);
return out;
}
list door_names = [];//door list
list door_num = [];//corresponding link numbers
list door_closed_rot = [];//corresponding closed state rotation
list door_direction = [];//which direction the door spin open
list door_open = [];//is the door open?
list door_open_time = [];//when was it open?
list door_acl = [];//who can open the door (by user id)
list door_pos = [];//the position of the door
list user_indexes = [];//list of users (user ids)
integer is_active = FALSE;//if this is false the script ignore touches
recount_doors()
{
//this function recount the doors and record all the different door characteristics
//only ran after script reset/when an object is linked/unlinked
is_active = FALSE;
llSetText("recounting doors...",<1.0,1.0,1.0>,1.0);
integer prims = llGetNumberOfPrims();
integer i;
for(i=2;i<=prims;i++)
{
key prim = llGetLinkKey(i);
list tmp = llGetObjectDetails(prim,[OBJECT_NAME,OBJECT_DESC,OBJECT_ROT,OBJECT_POS]);
string prim_name = llList2String(tmp,0);
string prim_descr = llList2String(tmp,1);
rotation prim_rot = (rotation)llList2String(tmp,2);
vector prim_pos = (vector)llList2String(tmp,3);
door_num += [i];
door_names += [prim_name];
door_closed_rot += [prim_rot];
door_open += [FALSE];
door_open_time += [0];
if(prim_descr == "right")
door_direction += [TRUE];
else
door_direction += [FALSE];
door_acl += [""];
door_pos += [prim_pos];
}
llSetText("...done!",<1,1,1>,1.0);
reload_acl();
}
string config = "config";//name of the configuration file
integer nLine = 0;//current line we are reading
//this function re read the config notecard and populate the
//user list and acl table
reload_acl()
{
llSetText("reloading access controls...",<1,1,1>,1.0);
is_active = FALSE;
nLine = 0;
//remove all acl
integer i;
for(i=0;i<llGetListLength(door_num);i++)
door_acl = llListReplaceList(door_acl,[""],i,i);
user_indexes = [];
llGetNotecardLine(config,nLine);
}
//close a door (by index) using the stored rotation
close(integer index)
{
integer linknum = llList2Integer(door_num,index);
rotation closed = llList2Rot(door_closed_rot,index);
llSetLinkPrimitiveParams(linknum,[PRIM_ROTATION,closed]);
door_open = llListReplaceList(door_open,[FALSE],index,index);
}
//close a door (by index) using the stored rotation and adding or substracting 90 degrees
//on the Z world axis depending of the direction recorded for the door.
//also record it's opening time (unix timestamp)
open(integer index)
{
integer linknum = llList2Integer(door_num,index);
rotation closed = llList2Rot(door_closed_rot,index);
rotation open;
if( llList2Integer(door_direction,index) )
open = llEuler2Rot(llRot2Euler(closed)+ (<0,0,90> *DEG_TO_RAD));
else
open = llEuler2Rot(llRot2Euler(closed)+ (<0,0,-90> *DEG_TO_RAD));
llSetLinkPrimitiveParams(linknum,[PRIM_ROTATION,open]);
door_open_time = llListReplaceList(door_open_time,[llGetUnixTime()],index,index);
door_open = llListReplaceList(door_open,[TRUE],index,index);
llSetTimerEvent(1.0);
}
//those 3 functions rez a sound emitter with it's destination position encoded in integer
play_open(vector pos)
{
llRezObject("open",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(pos));
}
play_close(vector pos)
{
llRezObject("close",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(pos));
}
play_lock(vector pos)
{
llRezObject("lock",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(pos));
}
default
{
touch_start(integer total_number)
{
integer userid;
if(!is_active)
return;
//considering we MAY receive more than one touch at the same time since
//we can manage many doors.
for(userid=0;userid<total_number;userid++)
{
integer door_id = llDetectedLinkNumber(userid);
string clicker_name = llDetectedName(userid);
integer door_index = llListFindList(door_num,[door_id]);
if(door_index == -1)
return;//unknown door? do nothing
integer is_open = llList2Integer(door_open,door_index);
vector door_vec = llList2Vector(door_pos,door_index);
//we do not accept touches that are further away from activation_distance
if( llVecDist(door_vec,llDetectedPos(userid) )> activation_distance )
llInstantMessage(llDetectedKey(userid),"You can't use this from this distance.");
else
{
if(is_open)
{ //if the door is open, simply play sound and close it.
play_close(door_vec);
close(door_index);
}
else
{
string acl_string = llList2String(door_acl,door_index);
//if the acl string is empty for this door we simply open it
if(acl_string == "") //no specific locking
{
play_open(door_vec);
open(door_index);
}
else
{
//otherwise we lookup if the userid that correspond to the person who touched
//the door match any of the ones in the ACL string
integer user_index = llListFindList(user_indexes,[clicker_name]);
if(user_index == -1) //we don't even know this user? sure as hell there is no acl about him
play_lock(door_vec);
else
{
list acl_list = llParseString2List(acl_string,[","],[]);
if(llListFindList(acl_list,[(string)user_index]) != -1)
{
play_open(door_vec);
open(door_index);
}
else
play_lock(door_vec);
}
}
}
}
}
}
dataserver(key id,string data)
{
//notecard reading stuff
if(data != EOF)
{
if(data != "" && data != " " && llGetSubString(data,0,1) != "//")
{
list command_and_data = llParseString2List(data,["="],[]);
string door_name = llList2String(command_and_data,0);
string user_names_string = llList2String(command_and_data,1);
integer index = llListFindList(door_names,[door_name]);
if(index != -1)
{
list user_names_list = llParseString2List(user_names_string,[","],[]);
integer j;
list pre_acl_list;
for(j=0;j<llGetListLength(user_names_list);j++)
{
string user_name = llList2String(user_names_list,j);
integer index2 = llListFindList(user_indexes,[user_name]);
if( index2 == -1)
{
pre_acl_list += llGetListLength(user_indexes);
user_indexes += [user_name];
}
else
pre_acl_list += [index2];
}
string pre_acl_string = llDumpList2String(pre_acl_list,",");
door_acl = llListReplaceList(door_acl,[pre_acl_string],index,index);
}
}
nLine++;
llGetNotecardLine(config,nLine);
}
else
{
is_active = TRUE;
llOwnerSay("config reloaded");
llSetText((string)llGetFreeMemory()+"bits free",<.5,.5,.5>,.5);
}
}
state_entry()
{
recount_doors();
}
changed(integer change)
{
//if we detect an inventory change we reread the notecard
//if we detect a linkchange we reset the script and recount doors first
if( (change & CHANGED_INVENTORY) == CHANGED_INVENTORY)
reload_acl();
if( (change & CHANGED_LINK) == CHANGED_LINK)
llResetScript();
}
timer()
{
//timer will run once a second as long as at least one door is open.
if(llListFindList(door_open,[TRUE]) == -1)
{
llSetTimerEvent(0.0);
return;
}
integer i;
//each run of the timer we loop through the timestamps to check if one of them is too old
//(which means we can force close the associated door
for(i=0;i<llGetListLength(door_open_time);i++)
{
integer is_open = llList2Integer(door_open,i);
integer time = llList2Integer(door_open_time,i);
if( is_open && ((time + autoclose_time) < llGetUnixTime()))
{
vector door_vec = llList2Vector(door_pos,i);
llRezObject("close",llGetPos(),ZERO_VECTOR,ZERO_ROTATION,vec2int(door_vec));
close(i);
}
}
}
}
Sound emitter script
You need this script in the 3 rezzable objects "open" "close" and "lock" in order to play your door sounds at the right place (At the time i wrote this , lsl doesn't allow yet to play sounds from an unscripted prim in a link set)
string sound_to_play = "my door sound";// put your sound name/key here
//This functions is from Nomad Padar, pretty awesome!
//decode from integer to vector
vector int2vec(integer n)
{
//0zyx ZZZZ ZZZZ ZZZZ YYYY YYYY XXXX XXXX
return <n&0xFF, (n>>8)&0xFF, ((n>>16)&0xFFF)> + <((n&0x10000000)!=0)*.5,((n&0x20000000)!=0)*.5,((n&0x40000000)!=0)*.5>;
}
default
{
state_entry()
{
llSetStatus(STATUS_PHANTOM, TRUE);
llSetPrimitiveParams([PRIM_TEMP_ON_REZ, TRUE]);
llSetTexture(TEXTURE_TRANSPARENT,ALL_SIDES);
}
on_rez(integer a)
{
if(a == 0)
return;
vector destination = int2vec(a);
integer i;
for(i=0 ; i<50 && (llGetPos() != destination) ; i++)
llSetLinkPrimitiveParamsFast(0, [PRIM_POSITION, destination]);
if(llGetPos() == destination)
llTriggerSound(sound_to_play,1.0);
llDie();
}
}
Example "config" notecard:
//lines starting with "//" are ignored //Syntax: one line per door in the format door_name=user name,user name
My fancy front door=Kyrah Abattoir My secret playroom door=Kyrah Abattoir,Timeless Prototype
//of course if you want to lock a door from anybody you can set it to something like this:
Mine entrance=condemned until further notice
--Kyrah Abattoir 18:46, 7 March 2010 (UTC)