Join us in Phaze Demesnes

LSL Script Library Home   Add a script Show All
Category: Contributor: Description
Door Timeless Prototype Timeless Linked Door Script.lsl
Timeless Linked Door Script.lsl
Timeless Linked Door Script.lsl

Download this script - Please use this link to get this script. If you see all the code on one long line, please use Wordpad or another editor, such as LSLEdit.exe. The .LSL file you will download is an ordinary text file.

1 // CATEGORY:Door
2 // DESCRIPTION:Timeless Linked Door Script.lsl
3 // ARCHIVED BY:Ferd Frederix
4
5
6 //------------------------------------------------------
7 // Timeless Linked Door Script by Timeless Prototype
8 //------------------------------------------------------
9 // The latest version of this script can always be found
10 // in the Library section of the wiki:
11 // http://www.secondlife.com/badgeo/
12 // This script is free to use, but whereever it is used
13 // the SCRIPT's permissions MUST be set to:
14 // [x] Next owner can modify
15 // [x] Next owner can copy
16 // [x] Next owner can transfer
17 // [x] Allow anyone to copy
18 // [x] Share with group
19
20 //------------------------------------------------------
21 // USAGE INSTRUCTIONS FOR EVERYDAY USE:
22 //------------------------------------------------------
23 // Say the following commands on channel 0:
24 // 'unlock' - Unlocks all doors in range.
25 // 'lock' - Locks all doors in range and allows
26 // only the permitted users to open it.
27 // To open the door, either Touch it, Walk into it or
28 // say 'open' or say 'close'.
29
30 //------------------------------------------------------
31 // USAGE INSTRUCTIONS FOR BUILDERS:
32 //------------------------------------------------------
33 // 1. Copy and paste this script into the door prim and
34 // change the settings (see further down).
35 // 2. The door prim must be linked to at least one other
36 // prim (could be linked to the house for example).
37 // 3. The door prim MUST NOT be the root prim.
38 // 4. Use Edit Linked Parts to move, rotate and size the
39 // door prim for the closed state.
40 // 5. When ready, stand close to the door and say
41 // '/door closed' (this records the closed door
42 // position, rotation and size to the object's
43 // name and description).
44 // 6. Use the Edit Linked parts to move, rotate and size
45 // the door prim for the opened state.
46 // 7. When ready, stand close to the door and say
47 // '/door opened' (this records the opened door
48 // position, rotation and size).
49 // 8. Once recorded it will not accept these commands
50 // again. If you do need to redo the settings then
51 // delete the Name and Description of the door prim
52 // (these are where the position information is
53 // stored), and then follow the steps above again.
54 // Note: deleting the object name won't save, so set
55 // the object name to 'Object' to reset the object
56 // name.
57
58 //------------------------------------------------------
59 // Change these settings to suit your needs.
60 //------------------------------------------------------
61 // To mute any/all of the sounds set the sound string(s)
62 // to "" (empty string).
63 // To get the UUID of a sound, right click on the sound
64 // in your inventory and choose "Copy Asset UUID", then
65 // paste the UUID in here.
66 string doorOpenSound = "cb340647-9680-dd5e-49c0-86edfa01b3ac";
67 string doorCloseSound = "e7ff1054-003d-d134-66be-207573f2b535";
68 string confirmedSound = "69743cb2-e509-ed4d-4e52-e697dc13d7ac";
69 string accessDeniedSound = "58da0f9f-42e5-8a8f-ee51-4fac6c247c98";
70 string doorBellSound = "ee871042-e272-d8ec-3d40-0b0cb3371346"; // Setting to empty stops door announcements too.
71 float autoCloseTime = 120.0; // 0 seconds to disable auto close.
72 integer allowGroupToo = TRUE; // Set to FALSE to disallow same group access to door.
73 list allowedAgentUUIDs = ["8efecbac-35de-4f40-89c1-2c772b83cafa"]; // Comma-separated, quoted list of avatar UUIDs who are allowed access to this door.
74 integer listenChannel = 0;
75
76
77 //------------------------------------------------------
78 // Leave the rest of the settings alone, these are
79 // handled by the script itself.
80 //------------------------------------------------------
81 integer isLocked = FALSE; // Only when the door is locked do the permissions apply.
82 integer isOpen = TRUE;
83 vector openPos = ZERO_VECTOR;
84 rotation openRot = ZERO_ROTATION;
85 vector openScale = ZERO_VECTOR;
86 vector closedPos = ZERO_VECTOR;
87 rotation closedRot = ZERO_ROTATION;
88 vector closedScale = ZERO_VECTOR;
89 key openerKey = NULL_KEY;
90 key closerKey = NULL_KEY;
91 integer isSetup = FALSE;
92 integer listenHandle = 0;
93 string avatarName = "";
94
95 mySayName(integer channel, string objectName, string message)
96 {
98 llSetObjectName(objectName);
99 llSay(0, "/me " + message);
100 llSetObjectName(name);
101 }
102
103 mySay(integer channel, string message)
104 {
106 llSetObjectName("Door");
107 llSay(0, message);
108 llSetObjectName(name);
109 }
110
111 myOwnerSay(string message)
112 {
114 llSetObjectName("Door");
115 llOwnerSay(message);
116 llSetObjectName(name);
117 }
118
119 mySoundConfirmed()
120 {
121 if (confirmedSound != "")
122 {
123 llTriggerSound(confirmedSound, 1.0);
124 }
125 }
126
127 mySoundAccessDenied()
128 {
129 if (accessDeniedSound != "")
130 {
131 llTriggerSound(accessDeniedSound, 1.0);
132 }
133 }
134
135 myGetDoorParams()
136 {
137 isSetup = FALSE;
138 if (llSubStringIndex(llGetObjectDesc(), "door;") == 0 && llSubStringIndex(llGetObjectName(), "door;") == 0)
139 {
140 list nameWords = llParseString2List(llGetObjectName(), [";"], []);
141 list descWords = llParseString2List(llGetObjectDesc(), [";"], []);
142 if (llGetListLength(nameWords) != 4 || llGetListLength(descWords) != 4)
143 {
144 myOwnerSay("The door prim's name and/or description has invalid syntax and/or number of parameters. Delete the door prim's name and description and setup the door prim again.");
145 }
146 else
147 {
148 openPos = (vector)llList2String(nameWords, 1);
149 openRot = (rotation)llList2String(nameWords, 2);
150 openScale = (vector)llList2String(nameWords, 3);
151 closedPos = (vector)llList2String(descWords, 1);
152 closedRot = (rotation)llList2String(descWords, 2);
153 closedScale = (vector)llList2String(descWords, 3);
154 isSetup = TRUE;
155 }
156 }
157 }
158
159 mySetDoorParams(vector openPos, rotation openRot, vector openScale, vector closedPos, rotation closedRot, vector closedScale)
160 {
161 llSetObjectName("door;" +
162 (string)openPos + ";" +
163 (string)openRot + ";" +
164 (string)openScale);
165 llSetObjectDesc("door;" +
166 (string)closedPos + ";" +
167 (string)closedRot + ";" +
168 (string)closedScale);
169 isSetup = TRUE;
170 }
171
172 integer myPermissionCheck(key id)
173 {
174 integer hasPermission = FALSE;
175 if (isLocked == FALSE)
176 {
177 hasPermission = TRUE;
178 }
179 else if (llGetOwnerKey(id) == llGetOwner())
180 {
181 hasPermission = TRUE;
182 }
183 else if (allowGroupToo == TRUE && llSameGroup(id))
184 {
185 hasPermission = TRUE;
186 }
187 else if (llListFindList(allowedAgentUUIDs, [(string)id]) != -1)
188 {
189 hasPermission = TRUE;
190 }
191 return hasPermission;
192 }
193
194 myOpenDoor()
195 {
196 isOpen = FALSE;
197 myToggleDoor();
198 }
199
200 myCloseDoor()
201 {
202 isOpen = TRUE;
203 myToggleDoor();
204 }
205
206 myToggleDoor()
207 {
208 if (isSetup == FALSE)
209 {
210 myOwnerSay("The door prim has not been configured yet. Please read the usage instructions in the door script.");
211 }
212 else if (llGetLinkNumber() == 0 || llGetLinkNumber() == 1)
213 {
214 myOwnerSay("The door prim must be linked to at least one other prim and the door prim must not be the root prim");
215 }
216 else
217 {
218 isOpen = !isOpen;
219 if (isOpen)
220 {
221 if (doorBellSound != "")
222 {
223 llTriggerSound(doorBellSound, 1.0);
224 if (avatarName != "")
225 {
226 mySayName(0, avatarName, "is at the door.");
227 avatarName = "";
228 }
229 }
230 if (doorOpenSound != "")
231 {
232 llTriggerSound(doorOpenSound, 1.0);
233 }
235 // Door API.
236 llMessageLinked(LINK_SET, 255, "cmd|door|opened", NULL_KEY);
237 }
238 else
239 {
240 if (doorCloseSound != "")
241 {
242 llTriggerSound(doorCloseSound, 1.0);
243 }
244 llSetPrimitiveParams([ PRIM_POSITION, closedPos, PRIM_ROTATION, ZERO_ROTATION * closedRot / llGetRootRotation(), PRIM_SIZE, closedScale ]);
245 // Door API.
246 llMessageLinked(LINK_SET, 255, "cmd|door|closed", NULL_KEY);
247 }
248
249 llSetTimerEvent(0.0);
250 if (isOpen == TRUE && autoCloseTime != 0.0)
251 {
252 llSetTimerEvent(autoCloseTime);
253 }
254 }
255 }
256
257 default
258 {
260 {
261 listenHandle = llListen(listenChannel, "", NULL_KEY, "");
262 myGetDoorParams();
263 }
264
265 touch_start(integer total_number)
266 {
267 if (myPermissionCheck(llDetectedKey(0)) == TRUE)
268 {
269 avatarName = llDetectedName(0);
270 myToggleDoor();
271 }
272 else
273 {
274 mySoundAccessDenied();
275 }
276 }
277
278 timer()
279 {
280 myCloseDoor();
281 }
282
284 {
285 // Door API. The API is here in case you want to create PIN entry keypads or whatever.
286 if (num == llGetLinkNumber())
287 {
288 if (str == "cmd|door|doOpen")
289 {
290 myOpenDoor();
291 }
292 else if (str == "cmd|door|doClose")
293 {
294 myCloseDoor();
295 }
296 }
297 if (str == "cmd|door|discover")
298 {
299 llMessageLinked(LINK_SET, 255, "cmd|door|discovered|" + (string)llGetKey(), id);
300 }
301 }
302
303 listen(integer channel, string name, key id, string message)
304 {
305 // Performance note: it's quicker to compare the strings than to compare permissions each time anyone says anything on this channel.
306 if (message == "open")
307 {
308 if (myPermissionCheck(id) == TRUE)
309 {
310 // Only open the door if the person is quite close to this door.
311 openerKey = id;
312 closerKey = NULL_KEY;
313 avatarName = name;
314 llSensor(name, id, AGENT, 5.0, TWO_PI);
315 }
316 else
317 {
318 mySoundAccessDenied();
319 }
320 }
321 else if (message == "close")
322 {
323 if (myPermissionCheck(id) == TRUE)
324 {
325 openerKey = NULL_KEY;
326 closerKey = id;
327 avatarName = name;
328 // Only close the door if the person is quite close to this door.
329 llSensor(name, id, AGENT, 5.0, TWO_PI);
330 }
331 else
332 {
333 mySoundAccessDenied();
334 }
335 }
336 else if (message == "lock")
337 {
338 if (myPermissionCheck(id) == TRUE)
339 {
340 isLocked = TRUE;
341 mySoundConfirmed();
342 }
343 else
344 {
345 mySoundAccessDenied();
346 }
347 }
348 else if (message == "unlock")
349 {
350 if (myPermissionCheck(id) == TRUE)
351 {
352 isLocked = FALSE;
353 mySoundConfirmed();
354 }
355 else
356 {
357 mySoundAccessDenied();
358 }
359 }
360 else if (message == "/door opened" && llSubStringIndex(llGetObjectName(), "door;") == -1)
361 {
362 if (llGetOwnerKey(id) == llGetOwner())
363 {
364 mySoundConfirmed();
365 openPos = llGetLocalPos();
366 openRot = llGetLocalRot();
367 openScale = llGetScale();
368 isOpen = TRUE;
369 if (! (closedPos == ZERO_VECTOR && closedRot == ZERO_ROTATION && closedScale == ZERO_VECTOR))
370 {
371 mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale);
372 }
373 }
374 else
375 {
376 mySoundAccessDenied();
377 }
378 }
379 else if (message == "/door closed" && llSubStringIndex(llGetObjectDesc(), "door;") == -1)
380 {
381 if (llGetOwnerKey(id) == llGetOwner())
382 {
383 mySoundConfirmed();
384 closedPos = llGetLocalPos();
385 closedRot = llGetLocalRot();
386 closedScale = llGetScale();
387 isOpen = FALSE;
388 if (! (openPos == ZERO_VECTOR && openRot == ZERO_ROTATION && openScale == ZERO_VECTOR))
389 {
390 mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale);
391 }
392 }
393 else
394 {
395 mySoundAccessDenied();
396 }
397 }
398 }
399
400 sensor(integer num_detected)
401 {
402 if (openerKey != NULL_KEY)
403 {
405 for (i = 0; i < num_detected; i++)
406 {
407 if (llDetectedKey(i) == openerKey && myPermissionCheck(llDetectedKey(i)) == TRUE)
408 {
409 myOpenDoor();
410 }
411 }
412 openerKey = NULL_KEY;
413 }
414 else
415 {
417 for (i = 0; i < num_detected; i++)
418 {
419 if (llDetectedKey(i) == closerKey && myPermissionCheck(llDetectedKey(i)) == TRUE)
420 {
421 myCloseDoor();
422 }
423 }
424 closerKey = NULL_KEY;
425 }
426 }
427
428 //------------------------------------------------------
429 // Uncomment the following code if you particularly want
430 // collisions to affect the door state.
431 //------------------------------------------------------
432
433 // collision_start(integer num_detected)
434 // {
435 // integer i;
436 // for (i = 0; i < num_detected; i++)
437 // {
438 // if (myPermissionCheck(llDetectedKey(i)) == TRUE)
439 // {
440 // avatarName = llDetectedName(i);
441 // myOpenDoor();
442 // }
443 // else if (llDetectedType(i) & AGENT)
444 // {
445 // mySoundAccessDenied();
446 // }
447 // }
448 // }
449
450 } // End of default state and end of script.
451 // END //