Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Fixed Steel Door Scripts

Cutter Rubio
Hopeless Romantic
Join date: 7 Feb 2004
Posts: 264
11-22-2004 17:35
As promised, here are the Steel Door Kit scripts that I've fixed so they now work again. I'm no expert, so hopefully this was the best way to do it, but it does work now :D

Here is the Door Controller Script:
CODE

// Door Lock Script -- JohnG Linden
// Edited to by Cutter Rubio to make it work with later LSL releases.

// To make this script open/close an actual door, the door should listen
// for the following messages on the following chat channel. One lock
// can control multiple doors if they all listen on the same channel.
//
// It is advisable for you to pick your own channel number so other locks
// in the area don't inadvertently open/close your door.
//
integer gLockChannel = 83;
string gOpenMsg = "MSG_OPEN";
string gCloseMsg = "MSG_CLOSE";
//
// Final note: if you need to open doors a long way from the lock, look
// for the functions door_open_msg() and door_close_msg() below, and
// change the llSay() to llShout().

// who owns this door
// this is changed by on_rez to whoever rezzed the door
string gAdministrator = "";

// who's in and who's out
// can be changed by the admin at runtime
list gAdmittedList =
[
];
list gBannedList =
[
];

// return values from permissions funcs
integer PERM_BANNED = -1;
integer PERM_NO = 0;
integer PERM_ADMIN = 1;
integer PERM_OK = 2;

// permission given to people not on any list
// if you just want to exclude people on the banned list and admit
// everyone else, set to PERM_OK
integer gDefaultPerm = PERM_OK;

// Note: this all would be much easier with lists that can contain lists,
// as people could have multiple properties hanging on them. Currently
// it's better than arrays but is still somewhat broken, because you have
// to assume a # of data fields instead of being able to traverse a list
// of lists.

//
// Helper functions here
// Uncomment as needed to enable some debug output
//

func_debug(string str)
{
// llSay(0, str);
}
debug(string str)
{
// llSay(0, str);
}
say(string str)
{
llSay(0, str);
}

// is name on admitted list?
integer check_admitted_list (string name)
{
if ( llListFindList(gAdmittedList, [name]) >= 0 )
{
return TRUE;
} else
{
return FALSE;
}
}

// is name on banned list?
integer check_banned_list (string name)
{
if ( llListFindList(gBannedList, [name]) >= 0 )
{
return TRUE;
} else
{
return FALSE;
}
}

// does name have perms to open the door?
integer check_permission (string name)
{
say("check_permission: " + name);
// admin always wins (and cannot ban themselves)
if ( name == gAdministrator ) return PERM_ADMIN;
// now check the plebeians
if ( check_banned_list(name) == TRUE ) return PERM_BANNED;
if ( check_admitted_list(name) == TRUE ) return PERM_OK;
// not on any lists, check default
return gDefaultPerm;
}

add_to_admitted_list (string name)
{
func_debug("add_to_admitted_list");

gAdmittedList = gAdmittedList + name;
}

add_to_banned_list (string name)
{
func_debug("add_to_banned_list");

gBannedList = gBannedList + name;
}

integer remove_from_admitted_list (string name)
{
func_debug("remove_from_admitted_list");

list lyst;

debug("admit: looking for " + name);

// search and destroy
integer index = llListFindList(gAdmittedList, [name]);
if ( index >= 0 )
{
debug("admit: found " + name);

// remove entry
gAdmittedList = llDeleteSubList(gAdmittedList, index, index);
return TRUE;
}

// couldn't find
debug("admit: can't find " + name);
return FALSE;
}

integer remove_from_banned_list (string name)
{
func_debug("remove_from_banned_list");

list lyst;

debug("ban: looking for " + name);

// search and destroy
integer index = llListFindList(gBannedList, [name]);
if ( index >= 0 )
{
debug("ban: found " + name);

// remove entry
gBannedList = llDeleteSubList(gBannedList, index, index);
return TRUE;
}

// couldn't find
debug("ban: can't find " + name);
return FALSE;
}

show_list (list src)
{
integer i;
integer len = llGetListLength(src);

for ( i = 0; i < len; ++i )
{
say(llList2String(src, i));
}
}

show_admitted_list ()
{
say("Admitted avatars:");
show_list (gAdmittedList);
}

show_banned_list ()
{
say("Banned avatars:");
show_list (gBannedList);
}

// parses incoming messages and does dirty work accordingly
parse_and_handle_message (string message)
{
func_debug("parse_and_handle_message");

string name;

// we only listen to admin, so no user check here
if ( "ban " == llGetSubString(message, 0, 3) )
{
name = llGetSubString(message, 4, -1);
if ( name != gAdministrator )
{
// note: no check for validity of usernames
add_to_banned_list (name);
remove_from_admitted_list (name);
say(name + " has been banned.");
} else
{
// error
say("You cannot ban yourself, Master.");
}
}
else if ( "admit " == llGetSubString(message, 0, 5) )
{
name = llGetSubString(message, 6, -1);
if ( name != gAdministrator )
{
add_to_admitted_list (name);
remove_from_banned_list (name);
say(name + " will now be admitted.");
} else
{
// error
say("You are already admitted, Master.");
}
}
else if ( "forget " == llGetSubString(message, 0, 6) )
{
name = llGetSubString(message, 7, -1);
// remove user from ban and admit lists
if ( remove_from_banned_list(name) )
{
say(name + "'s ban has been revoked.");
if ( gDefaultPerm == PERM_NO )
{
say("But the current default permissions still do not allow them");
say("to open this door.");
}
}
if ( remove_from_admitted_list(name) )
{
say(name + "'s access has been revoked.");
if ( gDefaultPerm == PERM_OK )
{
say("But the current default permissions still allow them");
say("to open this door.");
}
}
}
else if ( "list" == llGetSubString(message, 0, 3) )
{
say("Administrator: " + gAdministrator);
show_admitted_list();
show_banned_list();
if ( gDefaultPerm == PERM_NO )
{
say("Anyone not specifically admitted is denied entry.");
} else
{
say("Anyone not specifically banned is allowed entry.");
}
say("Type 'help' for full command list.");
}
else if ( "default admit" == llGetSubString(message, 0, 12) )
{
say("Anyone not specifically banned is now allowed entry.");
gDefaultPerm = PERM_OK;
}
else if ( "default ban" == llGetSubString(message, 0, 10) )
{
say("Anyone not specifically admitted is now denied entry.");
gDefaultPerm = PERM_NO;
}
else if ( "help" == llGetSubString(message, 0, 3) )
{
// list of commands
say("Command List:");
say("admit [name] -- grants access");
say("ban [name] -- revokes access");
say("list -- shows admit/ban lists");
say("forget [name] -- removes from admit and ban lists");
say("default admit -- anyone not specifically banned is admitted");
say("default ban -- anyone not specifically admitted is banned");
say("help -- this text");
}
}

// send messages to actual door
door_open_msg()
{
func_debug("door_open_msg");
llSay(gLockChannel, gOpenMsg);
}
door_close_msg()
{
llSay(gLockChannel, gCloseMsg);
}

//
// States
//

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

state_entry()
{
func_debug("default state_entry");
// set the owner to administrator
string owner = llKey2Name(llGetOwner());
if ( owner == "" )
{
say("FATAL ERROR: no owner!");
}
gAdministrator = owner;
say("Door Admin: " + owner);
// listen for the administrator
llListen(0, "", "", "");
// door starts out closed
state closed_state;
}

state_exit()
{
}
}

state closed_state
{
on_rez(integer param) { llResetScript(); }

state_entry()
{
func_debug("closed_state state_entry");
llPlaySound("lock_close", 0.7);
llListen(0, "", NULL_KEY, "");
// tell door to close
door_close_msg();
}

touch_start(integer num_touches)
{
func_debug("closed_state touch_start");
// currently we only address the first touch, if multiple
integer i = 0;
// who touched us?
string name = llDetectedName(i);
// can they open the door?
integer perm = check_permission(name);
if ( perm == PERM_ADMIN )
{
// Yes, master. I'd like a call to determine gender so
// I can say "mistress" when appropriate
say("Door opened, Master.");
state open_state;
} else if ( perm == PERM_OK )
{
// yep
say("Door opened for " + name);
state open_state;
} else if ( perm == PERM_BANNED )
{
// specifically denied
say(name + " is specifically prohibited from opening this door.");
} else
{
say(name + " is not permitted to open this door.");
}
}

listen(integer channel, string name, key id, string message)
{
func_debug("closed_state listen");
// note: we don't check name because we only listen to our admin
parse_and_handle_message (message);
}

state_exit()
{
}
}

state open_state
{
on_rez(integer param) { llResetScript(); }

state_entry()
{
func_debug("open_state state_entry");
llPlaySound("lock_open", 0.7);
llListen(0, "", NULL_KEY, "");
// tell door to open
door_open_msg();
}

touch_start(integer num_touches)
{
func_debug("open_state touch_start");
// currently we only address the first touch, if multiple
integer i = 0;
// who touched us?
string name = llDetectedName(i);
// can they open the door?
integer perm = check_permission(name);
if ( perm == PERM_ADMIN )
{
// Yes, master. I'd like a call to determine gender so
// I can say "mistress" when appropriate
say("Door closed, Master.");
state closed_state;
} else if ( perm == PERM_OK )
{
// yep
say("Door closed for " + name);
state closed_state;
} else if ( perm == PERM_BANNED )
{
// specifically denied
say(name + " is specifically prohibited from closing this door.");
} else
{
say(name + " is not permitted to close this door.");
}
}

listen(integer channel, string name, key id, string message)
{
func_debug("open_state listen");
// note: we don't check name because we only listen to our admin
parse_and_handle_message (message);
}

state_exit()
{
}
}


This is the matching script for the door object itself:
CODE

// Sliding door movement script
// JohnG Linden
// Edited by Cutter Rubio to make it work with later releases of LSL

// NOTE: these definitions should be the same as those from the lock
// object or the door will not actually work

integer gLockChannel = 83;
string gOpenMsg = "MSG_OPEN";
string gCloseMsg = "MSG_CLOSE";

// where we are when closed
vector gClosedPos;
rotation gClosedRot;
// internal timer for opening
float gOpenTimer;

// displacement when open
// NOTE: if you want it to open right, you can either rotate it 180 degrees
// around the Z axis or change this to <1.5, 0.0, 0.0>
vector gOpenDelta = <-1.5, 0.0, 0.0>;
// how long it takes to slide open
float gOpenTime = 1.6;
// how many steps along the way
float gOpenTimeStep = 0.2;

key gAdmin = "";

// sound we loop when opening/closing
string gSlideSound = "space_door";
float gSlideSoundVolume = 0.6;

//
// helper functions
//

func_debug(string str)
{
// llSay(0, str);
}
debug(string str)
{
// llSay(0, str);
}
say(string str)
{
llSay(0, str);
}

//
// states begin here
//

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

state_entry()
{
func_debug("default state_entry");
// no physics until we need to open/close
llSetStatus(STATUS_PHYSICS, FALSE);
// but set proper values here anyway
llSetBuoyancy(1.0);
// save position
gClosedPos = llGetPos();
gClosedRot = llGetRot();
gOpenTimer = 0.0;
gAdmin = llGetOwner();
// listen for open/close messages
llListen(gLockChannel, "", NULL_KEY, "");
// and go to closed state
state door_closed;
}
}

state door_closed
{
on_rez(integer arg) { llResetScript(); }

state_entry()
{
func_debug("door_closed state_entry");
// enforce proper location
llListen(gLockChannel, "", NULL_KEY, "");
llSetStatus(STATUS_PHYSICS, FALSE);
llSetPos(gClosedPos);
llSetRot(gClosedRot);
}

moving_end()
{
func_debug("moving_end");
// if we get moved, remember where we are
say("old pos: " + (string)gClosedPos);
gClosedPos = llGetPos();
gClosedRot = llGetRot();
say("new pos: " + (string)gClosedPos);
}

listen(integer channel, string name, key id, string msg)
{
if ( msg == gOpenMsg )
{
state door_opening;
}
}
}

state door_opening
{
on_rez(integer arg) { llResetScript(); }

state_entry()
{
func_debug("door_opening state_entry");
// start opening sound
llLoopSound(gSlideSound, gSlideSoundVolume);
// turn on physics
// doors should never rotate
llListen(gLockChannel, "", NULL_KEY, "");
llSetStatus(STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z, FALSE);
llSetStatus(STATUS_PHYSICS, TRUE);
// start opening process
llResetTime();
gOpenTimer = 0.0;
llSetTimerEvent(gOpenTimeStep);
}

timer()
{
float time = llGetTime();

if ( time > gOpenTime + gOpenTimeStep)
{
// stop timer interrupts
llSetTimerEvent(0.0);
// door is now open
state door_open;
} else
{
// interpolate proper position
vector pos = gOpenDelta * (time / gOpenTime);
// orient properly
pos *= gClosedRot;
// move there
llMoveToTarget(gClosedPos + pos, gOpenTimeStep * 1.5);

}
}

state_exit()
{
llStopSound();
}
}

state door_open
{
on_rez(integer arg) { llResetScript(); }

state_entry()
{
func_debug("door_open state_entry");
// enforce proper location
llListen(gLockChannel, "", NULL_KEY, "");
llSetStatus(STATUS_PHYSICS, FALSE);
llSetPos(gClosedPos + (gOpenDelta * gClosedRot));
llSetRot(gClosedRot);
}

listen(integer channel, string name, key id, string msg)
{
if ( msg == gCloseMsg )
{
state door_closing;
}
}
}

state door_closing
{
on_rez(integer arg) { llResetScript(); }

state_entry()
{
func_debug("door_closing state_entry");
// audio
llLoopSound(gSlideSound, gSlideSoundVolume);
// turn on physics
// doors should never rotate
llListen(gLockChannel, "", NULL_KEY, "");
llSetStatus(STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z, FALSE);
llSetStatus(STATUS_PHYSICS, TRUE);
// start opening process
llResetTime();
gOpenTimer = 0.0;
llSetTimerEvent(gOpenTimeStep);
}

timer()
{
float time = llGetTime();

if ( time > gOpenTime + gOpenTimeStep)
{
// stop timer interrupts
llSetTimerEvent(0.0);
// door is now open
state door_closed;
} else
{
// interpolate proper position
vector pos = gOpenDelta * (1.0 - (time / gOpenTime));
// orient properly
pos *= gClosedRot;
// move there
llMoveToTarget(gClosedPos + pos, gOpenTimeStep * 1.5);

}
}

state_exit()
{
// HACKISH: this is also done in the state_entry() of door_closed
// but the moving_end() callback gets called from normal door
// movement hanging over into the state. Evidently state_entry()
// doesn't have to finish before other callbacks happen, or else
// the llSetStatus() doesn't immediately stop physics-based motion
llListen(gLockChannel, "", NULL_KEY, "");
llSetStatus(STATUS_PHYSICS, FALSE);
llSetPos(gClosedPos);
llSetRot(gClosedRot);
// kill closing sound
llStopSound();
}
}
_____________________
The early bird may get the worm, but the second mouse gets the cheese.
Ramoth Darkholme
Registered User
Join date: 2 Dec 2004
Posts: 30
12-09-2004 20:36
There is an error compiling, Line 451, column 0.

integer gLockChannel = 83;

Syntax Error
Postmark Jensen
is not a jerk.
Join date: 23 May 2004
Posts: 281
12-13-2004 17:36
Ramoth: There are two code snippets in there. Put one in the door, the other in the controller. Don't try to compile the whole thing, cause it barfs from Cutter's note about where to stick it.
Ramoth Darkholme
Registered User
Join date: 2 Dec 2004
Posts: 30
12-15-2004 08:07
Ah thanks, got it working, now to find some sounds for it :)
Faith Stormwind
Second Life Resident
Join date: 10 Nov 2004
Posts: 4
12-15-2004 18:45
I use this now, GREAT script. TY soo much!
Baba Zhao
Registered User
Join date: 28 Sep 2006
Posts: 8
2 degrees of difference
04-14-2007 10:07
Very nice fix. No wonder the original wouldn't work. For me though the door rotates 2 degees less and stays there after first opening, i.e. if at 270 degrees, changes to 268, not true to wall (which stands at 270).
Baba Zhao
Registered User
Join date: 28 Sep 2006
Posts: 8
2 degrees of difference
04-14-2007 10:14
Script works great, now wonder the original did not. I do notice an initial rotation of 2 degrees on first opening and stays that way. 270 changes to 268 and stays at 268. The wall is at 270, so not true to wall.
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
Discussion Thread
04-21-2007 10:33
/54/cd/178770/1.html
_____________________
i've got nothing. ;)
Napoleon Aridian
Registered User
Join date: 3 May 2006
Posts: 6
Fixed door script still has a bug in it.
05-15-2007 16:37
Hi guys, I am having one issue with the door script.
When changing access permissions, anyone can do it yet the code states that it only listens to admin so no user check required.

I have tried to stop it from doing this but failed at every attempt.
I have no idea why I lets anyone ban, admit, forget and its bugging me lol
It also lets anyone show the help page and list of users which I would like to be for admin use only.

Many thanks
Nappy