Created
November 14, 2021 19:58
-
-
Save TimelessP/c0cbb8921c836b74cded41f694f06e4c to your computer and use it in GitHub Desktop.
LSL scripts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// myGetRoll(), myGetPitch(), myGetBearing(), mySetHorizonTexture() | |
// by Timeless Prototype | |
// Helps with attitude indicator (artificial horizon) display on a prim, plus a few other functions you will probably want for any flying vehicle instruments. | |
// Created 2009-12-01 | |
// Please give credit to Timeless Prototype in documentation when using anything from this script. | |
key craftKey = NULL_KEY; | |
// Returns the roll relative to the horizon (0.0), ranging from 90.0 (right wing down) to -90.0 (left wing down). Assumes frame of reference is East-facing at zero rotation. | |
float myGetRoll(rotation rot) | |
{ | |
vector vOffset = <0,1,0> * rot; | |
vector noX = <0.0, llVecMag(<0.0, vOffset.x, vOffset.y>), vOffset.z>; | |
float roll = llAtan2(noX.z, noX.y) * RAD_TO_DEG; | |
// However, this is the only indicator we're using to check if we're upside down. | |
// Therefore the only indicator we want to exceed the -90.0 and 90.0 thresholds. | |
vector upsideDownCheck = <0,0,1> * rot; | |
if (upsideDownCheck.z < 0.0) | |
{ | |
if (roll < 0.0) | |
{ | |
roll = -180.0 - roll; | |
} | |
else | |
{ | |
roll = 180.0 - roll; | |
} | |
} | |
return roll * DEG_TO_RAD; | |
} | |
// Returns the pitch relative to the horizon (0.0), ranging from 90.0 (up) to -90.0 (down). Assumes frame of reference is East-facing at zero rotation. | |
float myGetPitch(rotation rot) | |
{ | |
vector vOffset = <1,0,0> * rot; | |
vector noY = <llVecMag(<vOffset.x, vOffset.y, 0.0>), 0.0, vOffset.z>; | |
return llAtan2(noY.z, noY.x); | |
} | |
// Returns a compass bearing. Assumes frame of reference is East-facing at zero rotation. | |
float myGetBearing(rotation rot) | |
{ | |
vector vOffset = <1,0,0> * rot; | |
float bearing = llAtan2(vOffset.x, vOffset.y) * RAD_TO_DEG; | |
if (bearing < 0.0) | |
{ | |
bearing += 360.0; | |
} | |
return bearing * DEG_TO_RAD; | |
} | |
mySetHorizonTexture(rotation vehicleRotation, integer primFace) { | |
llSetPrimitiveParams([PRIM_TEXTURE, primFace, "973bb206-0812-89e6-21d3-a268f47dfa65", <0.3, 0.3, primFace>, <0.0, (myGetPitch(vehicleRotation)/6.39)-0.25, primFace>, myGetRoll(vehicleRotation)]); | |
} | |
default | |
{ | |
state_entry() | |
{ | |
llSetTimerEvent(0.0); | |
llListen(55, "", NULL_KEY, ""); | |
} | |
attach(key id) | |
{ | |
llSetTimerEvent(0.0); | |
} | |
listen(integer channel, string name, key id, string message) | |
{ | |
if (llSubStringIndex(message, "cmd|hud|connect|") == 0) | |
{ | |
key pilotId = (key)llGetSubString(message, 16, -1); | |
if (pilotId == llGetOwner()) | |
{ | |
craftKey = id; | |
llSetTimerEvent(0.5); | |
} | |
} | |
} | |
timer() | |
{ | |
list details = llGetObjectDetails(craftKey, [OBJECT_NAME, OBJECT_POS, OBJECT_ROT, OBJECT_VELOCITY]); | |
if (llList2String(details, 2) == "") | |
{ | |
llSetTimerEvent(0.0); | |
llOwnerSay("Vehicle has left the region. Please use autopilot features to control the vehicle."); | |
} | |
mySetHorizonTexture((rotation)llList2String(details, 2), 4); | |
} | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Timeless Linked Turret | |
// -------------------------- | |
// Description: LSL script to rotate a linked child prim locally | |
// around local z and y axes only to point at a position in | |
// the sim. Perfect for creating gun turrets that are linked | |
// to a vehicle. | |
// Version 1.0.13 27th September 2009 | |
// Concept by Timeless Prototype, 6th June 2008 | |
// Scripted by: Timeless Prototype | |
// With ideas and optimizations from: Jiminy Roo, Prime Oxide | |
// | |
// If you need help, please *only* get community support in forums, etc. | |
// Please do not contact the names above. | |
// | |
// This script is a gift to the scripters of Second Life from Timeless Prototype, | |
// and hopefully to be enjoyed by the community as widely as is the | |
// Timeless Linked Door script. <3 | |
// | |
// Usage: | |
// -------- | |
// This script belongs in the gun turret prim that is a child prim in a link set. | |
// | |
// 1. Set localJointPos variable to the relative offset within the linkset | |
// where the rotation point of the gun barrel prim will be. | |
// 2. Set the offsetFromJoint variable to how much the prim will need to | |
// be offset along its final rotation. For example: if the | |
// turret gun barrel is 5m long, setting offsetFromJoint to | |
// <2.5, 0.0, 0.0> will slide the barrel forwards by 2.5m, | |
// such that the back end of the barrel will touch the | |
// rotation point. | |
// 3. Set the frameOfref to the intended frame of reference. | |
// Example 1: barrel prim at zero rotation aims East; set | |
// frameOfRef to ZERO_ROTATION. | |
// Example 2: barrel prim at zero rotation aims up and | |
// under-side is facing East; set frameOfRef to | |
// llEuler2Rot(<0.0, PI_BY_TWO, 0.0>); | |
// Example 3: barrel prim at zero rotation aims down and | |
// under-side is facing West; set frameOfRef to | |
// llEuler2Rot(<0.0, -PI_BY_TWO, 0.0>); | |
// | |
// Your own tasks: Modify the script accordingly to make use of camera | |
// position and angle if you want to do mouselook aiming. This is merely | |
// the implementation of the function that rotates the child prim to point | |
// at the position in the sim. How you determine that position is up to the | |
// scripter (you). Have fun! :) | |
vector localJointPos = <0.79629, -0.65721, 0.30054>; | |
vector offsetFromJoint = <2.5, 0.0, 0.0>; | |
rotation frameOfRef = ZERO_ROTATION; | |
myPrimRotAt(vector target, vector rotPoint, vector offsetFromPoint, rotation frameOfReference) | |
{ | |
rotation rootRot = llGetRootRotation(); | |
vector direction = (target - (llGetRootPosition() + (rotPoint * rootRot))) / rootRot; | |
rotation rot = llEuler2Rot(<0.0, llAtan2(llVecMag(<direction.x, direction.y, 0.0>), direction.z) - PI_BY_TWO, 0.0>) * llEuler2Rot(<0.0, 0.0, llAtan2(direction.y, direction.x)>); | |
llSetPrimitiveParams([PRIM_ROTATION, frameOfReference * (rot / rootRot), PRIM_POSITION, rotPoint + (offsetFromPoint * rot)]); | |
} | |
default | |
{ | |
state_entry() | |
{ | |
frameOfRef = llEuler2Rot(<0,PI_BY_TWO,0>); | |
llSensorRepeat("", llGetOwner(), AGENT, 25.0, TWO_PI, 0.5); | |
} | |
sensor(integer num_detected) | |
{ | |
myPrimRotAt(llDetectedPos(0), localJointPos, offsetFromJoint, frameOfRef); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//------------------------------------------------------ | |
// Timeless Linked Door Script by Timeless Prototype | |
//------------------------------------------------------ | |
//====================================================== | |
// Modified by Yabu Kurosawa (feb 2008) | |
// As of server version 1.19.0, the length of the object | |
// name is always truncated to 63 characters, the length of the | |
// description to 127 characters. See also: | |
// http://blog.secondlife.com/2008/02/01/scripters-object-name-and-description-changes/ | |
// The original script exceeds the maximum name length. | |
// This problem is solved by compressing the 20 float | |
// values into 5-character strings and storing them all | |
// in the description field. Total string length is 105. | |
//====================================================== | |
// The original version of this script can always be found | |
// in the Library section of the wiki: | |
// http://www.secondlife.com/badgeo/ | |
// This script is free to use, but whereever it is used | |
// the SCRIPT's permissions MUST be set to: | |
// [x] Next owner can modify | |
// [x] Next owner can copy | |
// [x] Next owner can transfer | |
// [x] Allow anyone to copy | |
// [x] Share with group | |
//------------------------------------------------------ | |
// USAGE INSTRUCTIONS FOR EVERYDAY USE: | |
//------------------------------------------------------ | |
// Say the following commands on channel 0: | |
// 'unlock' - Unlocks all doors in range. | |
// 'lock' - Locks all doors in range and allows | |
// only the permitted users to open it. | |
// To open the door, either Touch it, Walk into it or | |
// say 'open' or say 'close'. | |
//------------------------------------------------------ | |
// USAGE INSTRUCTIONS FOR BUILDERS: | |
//------------------------------------------------------ | |
// 1. Copy and paste this script into the door prim and | |
// change the settings (see further down). | |
// 2. The door prim must be linked to at least one other | |
// prim (could be linked to the house for example). | |
// 3. The door prim MUST NOT be the root prim. | |
// 4. Use Edit Linked Parts to move, rotate and size the | |
// door prim for the closed state. | |
// 5. When ready, stand close to the door and say | |
// '/door closed' (this records the closed door | |
// position, rotation and size to the object's | |
// name and description). | |
// 6. Use the Edit Linked parts to move, rotate and size | |
// the door prim for the opened state. | |
// 7. When ready, stand close to the door and say | |
// '/door opened' (this records the opened door | |
// position, rotation and size). | |
// 8. Once recorded it will not accept these commands | |
// again. If you do need to redo the settings then | |
// delete the Description of the door prim | |
// (these are where the position information is | |
// stored), and then follow the steps above again. | |
//------------------------------------------------------ | |
// Change these settings to suit your needs. | |
//------------------------------------------------------ | |
// To mute any/all of the sounds set the sound string(s) | |
// to "" (empty string). | |
// To get the UUID of a sound, right click on the sound | |
// in your inventory and choose "Copy Asset UUID", then | |
// paste the UUID in here. | |
string doorOpenSound = "cb340647-9680-dd5e-49c0-86edfa01b3ac"; | |
string doorCloseSound = "e7ff1054-003d-d134-66be-207573f2b535"; | |
string confirmedSound = "69743cb2-e509-ed4d-4e52-e697dc13d7ac"; | |
string accessDeniedSound = "58da0f9f-42e5-8a8f-ee51-4fac6c247c98"; | |
string doorBellSound = "";//"ee871042-e272-d8ec-3d40-0b0cb3371346"; // Setting to empty stops door announcements too. | |
float autoCloseTime = 0.0; // 0 seconds to disable auto close. | |
integer allowGroupToo = TRUE; // Set to FALSE to disallow same group access to door. | |
list allowedAgentUUIDs = ["8efecbac-35de-4f40-89c1-2c772b83cafa"]; // Comma-separated, quoted list of avatar UUIDs who are allowed access to this door. | |
integer listenChannel = 0; | |
//------------------------------------------------------ | |
// Leave the rest of the settings alone, these are | |
// handled by the script itself. | |
//------------------------------------------------------ | |
integer isLocked = FALSE; // Only when the door is locked do the permissions apply. | |
integer isOpen = TRUE; | |
vector openPos = ZERO_VECTOR; | |
rotation openRot = ZERO_ROTATION; | |
vector openScale = ZERO_VECTOR; | |
vector closedPos = ZERO_VECTOR; | |
rotation closedRot = ZERO_ROTATION; | |
vector closedScale = ZERO_VECTOR; | |
key openerKey = NULL_KEY; | |
key closerKey = NULL_KEY; | |
integer isSetup = FALSE; | |
integer listenHandle = 0; | |
string avatarName = ""; | |
// code string used for the parameter encoding/decoding | |
string code68 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@$#&!?"; | |
mySayName(integer channel, string objectName, string message) | |
{ | |
string name = llGetObjectName(); | |
llSetObjectName(objectName); | |
llSay(0, "/me " + message); | |
llSetObjectName(name); | |
} | |
mySay(integer channel, string message) | |
{ | |
string name = llGetObjectName(); | |
llSetObjectName("Door"); | |
llSay(0, message); | |
llSetObjectName(name); | |
} | |
myOwnerSay(string message) | |
{ | |
string name = llGetObjectName(); | |
llSetObjectName("Door"); | |
llOwnerSay(message); | |
llSetObjectName(name); | |
} | |
mySoundConfirmed() | |
{ | |
if (confirmedSound != "") | |
{ | |
llTriggerSound(confirmedSound, 1.0); | |
} | |
} | |
mySoundAccessDenied() | |
{ | |
if (accessDeniedSound != "") | |
{ | |
llTriggerSound(accessDeniedSound, 1.0); | |
} | |
} | |
myGetDoorParams() | |
{ | |
isSetup = FALSE; | |
if (llSubStringIndex(llGetObjectDesc(), "door:") == 0) | |
{ | |
string s = llGetObjectDesc(); | |
integer k = 5; | |
openPos.x = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openPos.y = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openPos.z = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openRot.x = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openRot.y = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openRot.z = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openRot.s = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openScale.x = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openScale.y = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
openScale.z = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedPos.x = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedPos.y = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedPos.z = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedRot.x = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedRot.y = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedRot.z = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedRot.s = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedScale.x = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedScale.y = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
closedScale.z = decode_float( llGetSubString(s,k,k+4) ); k += 5; | |
isSetup = TRUE; | |
} | |
else | |
{ | |
myOwnerSay("The door prim's description is empty of has invalid syntax. Delete the door prim's description and setup the door prim again."); | |
} | |
} | |
mySetDoorParams(vector openPos, rotation openRot, vector openScale, vector closedPos, rotation closedRot, vector closedScale) | |
{ | |
string s = "door:"; | |
s += encode_float(openPos.x); | |
s += encode_float(openPos.y); | |
s += encode_float(openPos.z); | |
s += encode_float(openRot.x); | |
s += encode_float(openRot.y); | |
s += encode_float(openRot.z); | |
s += encode_float(openRot.s); | |
s += encode_float(openScale.x); | |
s += encode_float(openScale.y); | |
s += encode_float(openScale.z); | |
s += encode_float(closedPos.x); | |
s += encode_float(closedPos.y); | |
s += encode_float(closedPos.z); | |
s += encode_float(closedRot.x); | |
s += encode_float(closedRot.y); | |
s += encode_float(closedRot.z); | |
s += encode_float(closedRot.s); | |
s += encode_float(closedScale.x); | |
s += encode_float(closedScale.y); | |
s += encode_float(closedScale.z); | |
llSetObjectDesc(s); | |
isSetup = TRUE; | |
mySay(0,"Parameters are stored"); | |
} | |
integer myPermissionCheck(key id) | |
{ | |
integer hasPermission = FALSE; | |
if (isLocked == FALSE) | |
{ | |
hasPermission = TRUE; | |
} | |
else if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
hasPermission = TRUE; | |
} | |
else if (allowGroupToo == TRUE && llSameGroup(id)) | |
{ | |
hasPermission = TRUE; | |
} | |
else if (llListFindList(allowedAgentUUIDs, [(string)id]) != -1) | |
{ | |
hasPermission = TRUE; | |
} | |
return hasPermission; | |
} | |
myOpenDoor() | |
{ | |
isOpen = FALSE; | |
myToggleDoor(); | |
} | |
myCloseDoor() | |
{ | |
isOpen = TRUE; | |
myToggleDoor(); | |
} | |
myToggleDoor() | |
{ | |
if (isSetup == FALSE) | |
{ | |
myOwnerSay("The door prim has not been configured yet. Please read the usage instructions in the door script."); | |
} | |
else if (llGetLinkNumber() == 0 || llGetLinkNumber() == 1) | |
{ | |
myOwnerSay("The door prim must be linked to at least one other prim and the door prim must not be the root prim"); | |
} | |
else | |
{ | |
isOpen = !isOpen; | |
if (isOpen) | |
{ | |
if (doorBellSound != "") | |
{ | |
llTriggerSound(doorBellSound, 1.0); | |
if (avatarName != "") | |
{ | |
mySayName(0, avatarName, "is at the door."); | |
avatarName = ""; | |
} | |
} | |
if (doorOpenSound != "") | |
{ | |
llTriggerSound(doorOpenSound, 1.0); | |
} | |
llSetPrimitiveParams([ PRIM_POSITION, openPos, PRIM_ROTATION, ZERO_ROTATION * openRot / llGetRootRotation(), PRIM_SIZE, openScale ]); | |
// Door API. | |
llMessageLinked(LINK_SET, 255, "cmd|door|opened", NULL_KEY); | |
} | |
else | |
{ | |
if (doorCloseSound != "") | |
{ | |
llTriggerSound(doorCloseSound, 1.0); | |
} | |
llSetPrimitiveParams([ PRIM_POSITION, closedPos, PRIM_ROTATION, ZERO_ROTATION * closedRot / llGetRootRotation(), PRIM_SIZE, closedScale ]); | |
// Door API. | |
llMessageLinked(LINK_SET, 255, "cmd|door|closed", NULL_KEY); | |
} | |
llSetTimerEvent(0.0); | |
if (isOpen == TRUE && autoCloseTime != 0.0) | |
{ | |
llSetTimerEvent(autoCloseTime); | |
} | |
} | |
} | |
//========================================================================== | |
// encode a float with 7 digits precision into a 5-character string | |
// minimum=1e-31, maximum=1e+31 | |
// example: 1.234567 --> "hAM70" | |
//========================================================================== | |
string encode_float(float value) | |
{ | |
integer neg = 0; | |
integer exp = 0; | |
integer k = 0; | |
integer i; | |
integer n; | |
string s; | |
// get sign, make value positive | |
if( value < 0 ) | |
{ | |
neg = 1; | |
value = -value; | |
} | |
// scale value to 7 digits before decimal dot | |
if( value > 0 ) | |
{ | |
if( value > 1e31 ) value = 1e31; | |
if( value < 1e-31) value = 1e-31; | |
while( value >= 10000000 ) | |
{ | |
exp += 1; | |
value = value / 10; | |
} | |
while( value < 1000000 ) | |
{ | |
exp -= 1; | |
value = value * 10; | |
} | |
} | |
// round to integer, discard decimals | |
k = (integer)(value+0.5); | |
// encode exponent and sign into integer (should fit into 32 bit) | |
k = k*64 + (exp+38); | |
k = k*2 + neg; | |
// encode integer into string | |
s = ""; | |
for( i=0; i<5; i++ ) | |
{ | |
n = k % 68; | |
k = k / 68; | |
s = llGetSubString(code68,n,n) + s; | |
} | |
return s; | |
} | |
//========================================================================== | |
// decode a 5-character string into a float with 7 digits precision | |
// example: "hAM70" --> 1.234567 | |
//========================================================================== | |
float decode_float(string s) | |
{ | |
integer k = 0; | |
integer i; | |
integer neg; | |
float value; | |
integer exp; | |
// decode string into integer | |
for( i=0; i<5; i++ ) | |
{ | |
k = k*68 + llSubStringIndex(code68,llGetSubString(s,i,i)); | |
} | |
// extract sign and exponent | |
neg = k % 2; | |
k = k/2; | |
exp = k % 64 - 38; | |
k = k/64; | |
// convert into float | |
value = (float)k; | |
// scale according to exponent | |
while( exp > 0 ) | |
{ | |
value = value * 10; | |
exp -= 1; | |
} | |
while( exp < 0 ) | |
{ | |
value = value / 10; | |
exp += 1; | |
} | |
// insert sign | |
if( neg ) value = -value; | |
return value; | |
} | |
default | |
{ | |
state_entry() | |
{ | |
listenHandle = llListen(listenChannel, "", NULL_KEY, ""); | |
myGetDoorParams(); | |
} | |
touch_start(integer total_number) | |
{ | |
if (myPermissionCheck(llDetectedKey(0)) == TRUE) | |
{ | |
avatarName = llDetectedName(0); | |
myToggleDoor(); | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
timer() | |
{ | |
myCloseDoor(); | |
} | |
link_message(integer sender_num, integer num, string str, key id) | |
{ | |
// Door API. The API is here in case you want to create PIN entry keypads or whatever. | |
if (num == llGetLinkNumber()) | |
{ | |
if (str == "cmd|door|doOpen") | |
{ | |
myOpenDoor(); | |
} | |
else if (str == "cmd|door|doClose") | |
{ | |
myCloseDoor(); | |
} | |
} | |
if (str == "cmd|door|discover") | |
{ | |
llMessageLinked(LINK_SET, 255, "cmd|door|discovered|" + (string)llGetKey(), id); | |
} | |
} | |
listen(integer channel, string name, key id, string message) | |
{ | |
// Performance note: it's quicker to compare the strings than to compare | |
// permissions each time anyone says anything on this channel. | |
if (message == "open") | |
{ | |
if (myPermissionCheck(id) == TRUE) | |
{ | |
// Only open the door if the person is quite close to this door. | |
openerKey = id; | |
closerKey = NULL_KEY; | |
avatarName = name; | |
llSensor(name, id, AGENT, 5.0, TWO_PI); | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
else if (message == "close") | |
{ | |
if (myPermissionCheck(id) == TRUE) | |
{ | |
openerKey = NULL_KEY; | |
closerKey = id; | |
avatarName = name; | |
// Only close the door if the person is quite close to this door. | |
llSensor(name, id, AGENT, 5.0, TWO_PI); | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
else if (message == "lock") | |
{ | |
if (myPermissionCheck(id) == TRUE) | |
{ | |
isLocked = TRUE; | |
mySoundConfirmed(); | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
else if (message == "unlock") | |
{ | |
if (myPermissionCheck(id) == TRUE) | |
{ | |
isLocked = FALSE; | |
mySoundConfirmed(); | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
else if (message == "/door opened" && llSubStringIndex(llGetObjectDesc(), "door:") == -1) | |
{ | |
if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
mySoundConfirmed(); | |
openPos = llGetLocalPos(); | |
openRot = llGetLocalRot(); | |
openScale = llGetScale(); | |
isOpen = TRUE; | |
if (! (closedPos == ZERO_VECTOR && closedRot == ZERO_ROTATION && closedScale == ZERO_VECTOR)) | |
{ | |
mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale); | |
} | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
else if (message == "/door closed" && llSubStringIndex(llGetObjectDesc(), "door:") == -1) | |
{ | |
if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
mySoundConfirmed(); | |
closedPos = llGetLocalPos(); | |
closedRot = llGetLocalRot(); | |
closedScale = llGetScale(); | |
isOpen = FALSE; | |
if (! (openPos == ZERO_VECTOR && openRot == ZERO_ROTATION && openScale == ZERO_VECTOR)) | |
{ | |
mySetDoorParams(openPos, openRot, openScale, closedPos, closedRot, closedScale); | |
} | |
} | |
else | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
} | |
sensor(integer num_detected) | |
{ | |
if (openerKey != NULL_KEY) | |
{ | |
integer i; | |
for (i = 0; i < num_detected; i++) | |
{ | |
if (llDetectedKey(i) == openerKey && myPermissionCheck(llDetectedKey(i)) == TRUE) | |
{ | |
myOpenDoor(); | |
} | |
} | |
openerKey = NULL_KEY; | |
} | |
else | |
{ | |
integer i; | |
for (i = 0; i < num_detected; i++) | |
{ | |
if (llDetectedKey(i) == closerKey && myPermissionCheck(llDetectedKey(i)) == TRUE) | |
{ | |
myCloseDoor(); | |
} | |
} | |
closerKey = NULL_KEY; | |
} | |
} | |
collision_start(integer num_detected) | |
{ | |
integer i; | |
for (i = 0; i < num_detected; i++) | |
{ | |
if (myPermissionCheck(llDetectedKey(i)) == TRUE) | |
{ | |
avatarName = llDetectedName(i); | |
myOpenDoor(); | |
} | |
else if (llDetectedType(i) & AGENT) | |
{ | |
mySoundAccessDenied(); | |
} | |
} | |
} | |
} // End of default state and end of script. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Timeless Storage Crate - Mover | |
// by Timeless Prototype | |
// 2007-11-04 | |
// 1. Place this script in the objects that will be rezzed. | |
// 2. Place copies of the objects in the storage prim. | |
// 3. Ensure the Storage script is in the storage prim. | |
// 4. Touch the storage prim and Save locations. | |
integer isAboutToMove = FALSE; | |
integer rezzerId = 0; | |
integer lh = 0; | |
default | |
{ | |
state_entry() | |
{ | |
if (llGetObjectName() == "Object") | |
{ | |
state awaitNameChange; | |
} | |
lh = llListen(23, "", NULL_KEY, ""); | |
} | |
state_exit() | |
{ | |
llListenRemove(lh); | |
} | |
on_rez(integer start_param) | |
{ | |
isAboutToMove = TRUE; | |
rezzerId = start_param; | |
} | |
listen(integer channel, string name, key id, string message) | |
{ | |
if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
if ((llSubStringIndex(message, "cmd|crate|store|") == 0 && (rezzerId == 0 || (integer)llGetSubString(message, 16, -1) == rezzerId)) || (message == "cmd|crate|append" && rezzerId == 0)) | |
{ | |
llRegionSay(23, "cmd|crate|add|" + (string)llGetPos() + "|" + (string)llGetRootRotation()); | |
} | |
else if (llSubStringIndex(message, "cmd|crate|derez|") == 0) | |
{ | |
// check the id matches | |
integer theId = (integer)llGetSubString(message, 16, -1); | |
if (theId == rezzerId) | |
{ | |
llDie(); | |
} | |
} | |
else if (llSubStringIndex(message, "cmd|crate|moverelative|") == 0 && isAboutToMove == TRUE) | |
{ | |
isAboutToMove = FALSE; | |
list tokens = llParseStringKeepNulls(message, ["|"], []); | |
vector pos = llGetPos() + (vector)llList2String(tokens, 3); | |
rotation rot = (rotation)llList2String(tokens, 4); | |
llSetRot(rot); | |
integer timeout = 1000; | |
while (llVecDist(llGetPos(), pos) > 0.01) | |
{ | |
llSetPos(pos); | |
} | |
} | |
else if (llSubStringIndex(message, "cmd|crate|setid|") == 0) | |
{ | |
list tokens = llParseStringKeepNulls(message, ["|"], []); | |
key theKey = (key)llList2String(tokens, 3); | |
integer theId = (integer)llList2String(tokens, 4); | |
if (llGetKey() == theKey) | |
{ | |
rezzerId = theId; | |
} | |
} | |
} | |
} | |
} | |
state awaitNameChange | |
{ | |
state_entry() | |
{ | |
llOwnerSay("This object needs to be given a unique name to activate this script"); | |
llSetTimerEvent(1.0); | |
} | |
state_exit() | |
{ | |
llSetTimerEvent(0.0); | |
} | |
timer() | |
{ | |
if (llGetObjectName() != "Object") | |
{ | |
llOwnerSay("This object can now be stored"); | |
state default; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Timeless Storage Crate - Storage | |
// by Timeless Prototype | |
// 2007-11-04 | |
// 1. Place this script in the storage prim. | |
// 2. Follow instructions in the Mover script. | |
float storageTimeout = 15.0; // seconds | |
list objects = []; | |
integer index = 0; | |
integer lh = 0; | |
integer uniqueId = 0; | |
integer wasTouched = FALSE; | |
integer append = FALSE; | |
chooseAnotherId() | |
{ | |
uniqueId = 0; | |
while (uniqueId == 0) | |
{ | |
uniqueId = (integer)llFrand(30000.0); | |
} | |
llRegionSay(23, "cmd|crate|doesanyonehaveid|" + (string)uniqueId); | |
} | |
rezObject(integer index) | |
{ | |
llSetTimerEvent(0.0); | |
string object = llList2String(objects, index); | |
list tokens = llParseStringKeepNulls(object, ["|"], []); | |
string name = llList2String(tokens, 0); | |
vector pos = (vector)llList2String(tokens, 1); | |
rotation rot = (rotation)llList2String(tokens, 2) * llGetRot(); | |
llRezAtRoot(name, llGetPos(), ZERO_VECTOR, rot, uniqueId); | |
llSetTimerEvent(5.0); | |
} | |
default | |
{ | |
state_entry() | |
{ | |
if (uniqueId == 0) | |
{ | |
state findUniqueId; | |
} | |
lh = llListen(23, "", NULL_KEY, ""); | |
llSetText("Touch for menu\n" + (string)llGetListLength(objects) + " positions stored\n" + (string)llGetFreeMemory() + " bytes free", <1,1,1>, 1.0); | |
} | |
state_exit() | |
{ | |
llListenRemove(lh); | |
} | |
touch_start(integer total_number) | |
{ | |
if (llGetOwnerKey(llDetectedKey(0)) == llGetOwner()) | |
{ | |
wasTouched = TRUE; | |
llDialog(llDetectedKey(0), "Select an operation:", ["Store", "Append", "Derez", "Rez"], 23); | |
} | |
} | |
on_rez(integer start_param) | |
{ | |
state findUniqueId; | |
} | |
listen(integer channel, string name, key id, string message) | |
{ | |
if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
if (message == "Store" && wasTouched == TRUE) | |
{ | |
wasTouched = FALSE; | |
append = FALSE; | |
state store; | |
} | |
else if (message == "Append" && wasTouched == TRUE) | |
{ | |
wasTouched = FALSE; | |
append = TRUE; | |
state store; | |
} | |
else if (message == "Derez" && wasTouched == TRUE) | |
{ | |
wasTouched = FALSE; | |
llRegionSay(23, "cmd|crate|derez|" + (string)uniqueId); | |
} | |
else if (message == "Rez" && wasTouched == TRUE) | |
{ | |
wasTouched = FALSE; | |
if (objects == []) | |
{ | |
llOwnerSay("Nothing was stored yet"); | |
} | |
else | |
{ | |
state rez; | |
} | |
} | |
if (llSubStringIndex(message, "cmd|crate|doesanyonehaveid|") == 0) | |
{ | |
integer theId = (integer)llGetSubString(message, 27, -1); | |
if (theId == uniqueId) | |
{ | |
llRegionSay(23, "cmd|crate|ihaveid|" + (string)uniqueId); | |
} | |
} | |
} | |
} | |
} | |
state store | |
{ | |
state_entry() | |
{ | |
llOwnerSay("Storing..."); | |
lh = llListen(23, "", NULL_KEY, ""); | |
if (append == FALSE) | |
{ | |
objects = []; | |
llRegionSay(23, "cmd|crate|store|" + (string)uniqueId); | |
} | |
else | |
{ | |
llRegionSay(23, "cmd|crate|append"); | |
} | |
llSetTimerEvent(storageTimeout); | |
} | |
state_exit() | |
{ | |
llSetTimerEvent(0.0); | |
llOwnerSay("Storage completed, " + (string)llGetListLength(objects) + " positions stored"); | |
llListenRemove(lh); | |
} | |
timer() | |
{ | |
state default; | |
} | |
listen(integer channel, string name, key id, string message) | |
{ | |
if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
if (llSubStringIndex(message, "cmd|crate|add|") == 0) | |
{ | |
llSetTimerEvent(0.0); | |
if (llGetInventoryType(name) == INVENTORY_OBJECT) | |
{ | |
list tokens = llParseStringKeepNulls(message, ["|"], []); | |
vector pos = ((vector)llList2String(tokens, 3) - llGetPos()) / llGetRot(); | |
rotation rot = (rotation)llList2String(tokens, 4) / llGetRot(); | |
objects += [name + "|" + (string)pos + "|" + (string)rot]; | |
llSetText("Positions stored: " + (string)llGetListLength(objects), <1,1,1>, 1.0); | |
// set the id in the object | |
llRegionSay(23, "cmd|crate|setid|" + (string)id + "|" + (string)uniqueId); | |
} | |
llSetTimerEvent(storageTimeout); | |
} | |
} | |
} | |
} | |
state rez | |
{ | |
state_entry() | |
{ | |
index = 0; | |
llOwnerSay("Rezzing..."); | |
rezObject(index); | |
} | |
state_exit() | |
{ | |
llSetTimerEvent(0.0); | |
llOwnerSay("Rezzing complete"); | |
} | |
timer() | |
{ | |
string name = llList2String(llParseStringKeepNulls(llList2String(objects, index), ["|"], []), 0); | |
llOwnerSay("Rez operation for '" + name + "' timed out, parcel full, object removed from contents or insufficient parcel permissions?"); | |
state default; | |
} | |
object_rez(key id) | |
{ | |
llSetTimerEvent(0.0); | |
// tell it where to go and how to rotate relative to our rotation and position | |
string object = llList2String(objects, index); | |
list tokens = llParseStringKeepNulls(object, ["|"], []); | |
string name = llList2String(tokens, 0); | |
vector pos = (vector)llList2String(tokens, 1) * llGetRot(); | |
rotation rot = (rotation)llList2String(tokens, 2) * llGetRot(); | |
llWhisper(23, "cmd|crate|moverelative|" + (string)pos + "|" + (string)rot); | |
if (index + 1 == llGetListLength(objects)) | |
{ | |
state default; | |
} | |
else | |
{ | |
index++; | |
rezObject(index); | |
} | |
} | |
} | |
state findUniqueId | |
{ | |
state_entry() | |
{ | |
lh = llListen(23, "", NULL_KEY, ""); | |
llSetText("Assigning unique identifier to this crate...", <1,1,1>, 1.0); | |
chooseAnotherId(); | |
llSetTimerEvent(5.0); | |
} | |
state_exit() | |
{ | |
llSetTimerEvent(0.0); | |
llListenRemove(lh); | |
} | |
listen(integer channel, string name, key id, string message) | |
{ | |
if (llGetOwnerKey(id) == llGetOwner()) | |
{ | |
if (llSubStringIndex(message, "cmd|crate|ihaveid|") == 0) | |
{ | |
integer theId = (integer)llGetSubString(message, 17, -1); | |
if (theId == uniqueId) | |
{ | |
llSetTimerEvent(0.0); | |
chooseAnotherId(); | |
llSetTimerEvent(5.0); | |
} | |
} | |
} | |
} | |
timer() | |
{ | |
state default; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment