commit
3dac7b989a
@ -0,0 +1,570 @@ |
||||
list Keys; |
||||
float configRotTime = 1.0; |
||||
integer configRotSteps = 2; |
||||
integer configReverse = 0; |
||||
integer configRotAngle = 90; |
||||
string configAxis = "z"; |
||||
integer configAxisCenter= FALSE; |
||||
integer configAxisCenterDir = 1; |
||||
string configAxisCenterAxis = "x"; |
||||
float configAutoClose = 0.0; |
||||
float configDistance = 2.0; |
||||
//integer configCollide = FALSE; |
||||
integer configSensor = FALSE; |
||||
string configDouble = ""; |
||||
string soundOpen = "Door open"; |
||||
string soundClose = "Door close"; |
||||
string soundLock = "Lock"; |
||||
string soundUnlock = "Unlock"; |
||||
string soundKnock = "Door knock"; |
||||
|
||||
integer accessLoaded = FALSE; |
||||
integer doorLock = FALSE; |
||||
integer doorClosed = TRUE; |
||||
integer doorControl = FALSE; |
||||
key doorActUID = NULL_KEY; |
||||
float doorActDist = 0.0; |
||||
float touchTime; |
||||
float touchDouble = FALSE; |
||||
integer touchDrag = FALSE; |
||||
key doubleID = NULL_KEY; |
||||
|
||||
integer settingsLine = 0; |
||||
key settingsKey = NULL_KEY; |
||||
integer settingsSection = 0; // 1=settings, 2=keys |
||||
|
||||
|
||||
sound(string name) |
||||
{ |
||||
if (llGetInventoryType(name) == INVENTORY_SOUND) { |
||||
llPlaySound(name, 1.0); |
||||
} |
||||
else if (osIsUUID(name)) { |
||||
llPlaySound(name, 1.0); |
||||
} |
||||
} |
||||
|
||||
addKey(string data, integer send) |
||||
{ |
||||
if (llStringLength(data) > 0) { |
||||
string name = data; |
||||
name = llStringTrim(name, STRING_TRIM_HEAD); |
||||
name = llStringTrim(name, STRING_TRIM_TAIL); |
||||
|
||||
if (llGetSubString(name, 0, 0) == "#") return; |
||||
Keys = Keys + name; |
||||
if (send) llMessageLinked(LINK_ALL_OTHERS, 1, name, "addkey"); |
||||
} |
||||
} |
||||
|
||||
string trimString(string data) |
||||
{ |
||||
if (llStringLength(data) > 0) { |
||||
data = llStringTrim(data, STRING_TRIM_HEAD); |
||||
data = llStringTrim(data, STRING_TRIM_TAIL); |
||||
|
||||
if (llGetSubString(data, 0, 0) == "#") return ""; |
||||
else return data; |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
doorMsg(integer status, string part) |
||||
{ |
||||
if (llStringLength(configDouble) > 0) { |
||||
llMessageLinked(LINK_ALL_OTHERS, status, configDouble, part); |
||||
} |
||||
} |
||||
|
||||
lock(integer lock, string name) { |
||||
if (doorLock != lock) { |
||||
if (!doorLock) { |
||||
doorLock = TRUE; |
||||
doorMsg(doorLock, "lock"); |
||||
llSay(0, "/me locked."); |
||||
sound(soundLock); |
||||
} else { |
||||
doorLock = FALSE; |
||||
doorMsg(doorLock, "lock"); |
||||
llSay(0, "/me unlocked."); |
||||
sound(soundUnlock); |
||||
} |
||||
} |
||||
} |
||||
|
||||
loadSettings() |
||||
{ |
||||
settingsLine = 0; |
||||
settingsSection = 0; |
||||
settingsKey = NULL_KEY; |
||||
|
||||
if (loadSettings(1)) { |
||||
return; |
||||
} else { |
||||
loadSettings(2); |
||||
} |
||||
} |
||||
|
||||
integer loadSettings(integer section) |
||||
{ |
||||
if (section == 1) { |
||||
if (llGetInventoryType("Settings") == INVENTORY_NOTECARD) { |
||||
settingsLine = 0; |
||||
settingsSection = 1; |
||||
settingsKey = llGetNotecardLine("Settings", settingsLine); |
||||
|
||||
return TRUE; |
||||
} else { |
||||
return FALSE; |
||||
} |
||||
} |
||||
else if (section == 2) { |
||||
if (llGetInventoryType("Access List") == INVENTORY_NOTECARD) { |
||||
settingsLine = 0; |
||||
settingsSection = 2; |
||||
accessLoaded = TRUE; |
||||
settingsKey = llGetNotecardLine("Access List", settingsLine); |
||||
|
||||
return TRUE; |
||||
} else { |
||||
Keys = []; |
||||
accessLoaded = FALSE; |
||||
llMessageLinked(LINK_ALL_OTHERS, 0, "", "getkeys"); |
||||
return FALSE; |
||||
} |
||||
} |
||||
|
||||
return FALSE; |
||||
} |
||||
|
||||
|
||||
default |
||||
{ |
||||
state_entry() |
||||
{ |
||||
state loading; |
||||
} |
||||
|
||||
//collision_start(integer total_number) |
||||
//{ |
||||
// if (llDetectedType(0) & AGENT) |
||||
// if (!doorLock && doorClosed && configCollide) door(); |
||||
//} |
||||
|
||||
} |
||||
|
||||
state loading |
||||
{ |
||||
state_entry() |
||||
{ |
||||
loadSettings(); |
||||
} |
||||
|
||||
dataserver(key qid, string data) |
||||
{ |
||||
if (qid == settingsKey) { |
||||
if (data != EOF) { |
||||
if (settingsLine == 0 && settingsSection == 2) { |
||||
Keys = []; |
||||
llMessageLinked(LINK_ALL_OTHERS, 0, "", "clearkeys"); |
||||
llSleep(1.0); |
||||
} |
||||
|
||||
data = trimString(data); |
||||
|
||||
if (data != "" && llStringLength(data) > 0) { |
||||
if (settingsSection == 1) { |
||||
list part = llParseString2List(data, ["="], []); |
||||
|
||||
if (llToLower(llList2String(part, 0)) == "time") { |
||||
if (llList2Float(part, 1) > 0 && llList2Float(part, 1) <= 10) |
||||
configRotTime = llList2Float(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "steps") { |
||||
if (llList2Integer(part, 1) > 0) |
||||
configRotSteps = llList2Integer(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "angle") { |
||||
if (llAbs(llList2Integer(part, 1)) > 0 && llAbs(llList2Integer(part, 1)) < 360) |
||||
configRotAngle = llList2Integer(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "axis") { |
||||
if (llListFindList(["x", "X", "y", "Y", "z", "Z"], llList2List(part, 1, 1)) >= 0) { |
||||
configAxis = llToLower(llList2String(part, 1)); |
||||
} |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "axisoffset") { |
||||
if (llToLower(llList2String(part, 1)) == "edge") |
||||
configAxisCenter = FALSE; |
||||
else if (llToLower(llList2String(part, 1)) == "center") |
||||
configAxisCenter = TRUE; |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "axisoffsetbase") { |
||||
if (llGetSubString(llList2String(part, 1), 0, 0) == "-") { |
||||
configAxisCenterDir = -1; |
||||
} else { |
||||
configAxisCenterDir = 1; |
||||
} |
||||
if (llListFindList(["x", "y", "z"], [ llToLower(llGetSubString(llList2String(part, 1), 0, 0)) ]) >= 0) { |
||||
configAxisCenterAxis = llToLower(llGetSubString(llList2String(part, 1), 0, 0)); |
||||
} |
||||
else if (llListFindList(["x", "y", "z"], [ llToLower(llGetSubString(llList2String(part, 1), 1, 1)) ]) >= 0) { |
||||
configAxisCenterAxis = llToLower(llGetSubString(llList2String(part, 1), 1, 1)); |
||||
} |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "autoclose") { |
||||
if (llList2Float(part, 1) >= 0 && llList2Float(part, 1) <= 300) |
||||
configAutoClose = llList2Float(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "touchdist") { |
||||
if (llList2Float(part, 1) >= 0) { |
||||
configDistance = llList2Float(part, 1); |
||||
} else { |
||||
configDistance = 2.0; |
||||
} |
||||
} |
||||
//else if (llToLower(llList2String(part, 0)) == "collision") { |
||||
// if (llList2Integer(part, 1) >= 0) |
||||
// configCollide = llList2Integer(part, 1); |
||||
//} |
||||
else if (llToLower(llList2String(part, 0)) == "sensor") { |
||||
if (llList2Integer(part, 1) >= 1) |
||||
configSensor = llList2Integer(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "double_name") { |
||||
if (llStringLength(llList2String(part, 1)) > 0) { |
||||
configDouble = llList2String(part, 1); |
||||
} else { |
||||
configDouble = ""; |
||||
} |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "sound_open") { |
||||
soundOpen = llList2String(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "sound_close") { |
||||
soundClose = llList2String(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "sound_knock") { |
||||
soundKnock = llList2String(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "sound_lock") { |
||||
soundLock = llList2String(part, 1); |
||||
} |
||||
else if (llToLower(llList2String(part, 0)) == "sound_unlock") { |
||||
soundUnlock = llList2String(part, 1); |
||||
} |
||||
} |
||||
else if (settingsSection == 2) { |
||||
addKey(data, TRUE); |
||||
} |
||||
} |
||||
|
||||
if (settingsSection == 1) |
||||
settingsKey = llGetNotecardLine("Settings", ++settingsLine); |
||||
else |
||||
settingsKey = llGetNotecardLine("Access List", ++settingsLine); |
||||
} else { |
||||
if (settingsSection == 1) { |
||||
llSay(0, "Settings loaded."); |
||||
loadSettings(2); |
||||
} else { |
||||
llSay(0, "Access List loaded. " + (string)llGetListLength(Keys) + " with access."); |
||||
if (doorClosed) state closed; |
||||
else state opened; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
state closed |
||||
{ |
||||
state_entry() |
||||
{ |
||||
doorClosed = TRUE; |
||||
} |
||||
|
||||
changed(integer change) |
||||
{ |
||||
if (change & CHANGED_INVENTORY) { |
||||
state loading; |
||||
} |
||||
} |
||||
|
||||
touch_start(integer total_number) |
||||
{ |
||||
if (configDistance > 0.0) { |
||||
if (llVecDist(llGetPos(), llDetectedPos(0)) <= configDistance) { |
||||
llResetTime(); |
||||
if (touchDrag) touchDrag = FALSE; |
||||
} |
||||
} |
||||
} |
||||
|
||||
touch(integer total_number) |
||||
{ |
||||
if (configDistance > 0.0) { |
||||
if (llVecDist(llGetPos(), llDetectedPos(0)) <= configDistance) { |
||||
if (llGetTime() >= 0.25 && !touchDrag) { |
||||
touchDrag = TRUE; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
touch_end(integer total_number) |
||||
{ |
||||
if (configDistance > 0.0) { |
||||
if (llVecDist(llGetPos(), llDetectedPos(0)) <= configDistance) { |
||||
if (touchDrag) { |
||||
if (llListFindList(Keys, [ llDetectedName(0) ]) > -1) { |
||||
if (doorLock) lock(FALSE, llDetectedName(0)); |
||||
else lock(TRUE, llDetectedName(0)); |
||||
} |
||||
llSetTimerEvent(0.0); |
||||
touchDrag = FALSE; |
||||
} |
||||
else if (llGetTime() >= 1) { |
||||
sound(soundKnock); |
||||
llSay(0, llDetectedName(0) + " knocks."); |
||||
llSetTimerEvent(0.0); |
||||
} |
||||
else { |
||||
if (!doorLock) { |
||||
doorControl = TRUE; |
||||
doorActUID = llDetectedKey(0); |
||||
doorActDist = llVecDist(llGetPos(), llDetectedPos(0)); |
||||
state opening; |
||||
//door(llDetectedKey(0), llVecDist(llGetPos(), llDetectedPos(0))); |
||||
} |
||||
else { |
||||
sound(soundKnock); |
||||
llSay(0, llDetectedName(0) + " knocks."); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
link_message(integer sender, integer num, string name, key id) |
||||
{ |
||||
if (llStringLength(configDouble) > 0 && name == configDouble) { |
||||
if (id == "door") { |
||||
if (doorControl) return; |
||||
//llOwnerSay("DEBUG: link_message:door: sender=" + (string)sender + ", num=" + (string)num); |
||||
if (num == FALSE) state opening; |
||||
} |
||||
else if (id == "lock") { |
||||
doorLock = num; |
||||
} |
||||
} |
||||
if (!accessLoaded) { |
||||
if (id == "clearkeys") { |
||||
Keys = []; |
||||
} |
||||
else if (id == "addkey") { |
||||
addKey(name, FALSE); |
||||
} |
||||
} else { |
||||
if (id == "getkeys") { |
||||
integer i; |
||||
|
||||
for (i = 0; i < llGetListLength(Keys); i++) { |
||||
llMessageLinked(sender, 1, llList2String(Keys, i), "addkey"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
state opened |
||||
{ |
||||
state_entry() |
||||
{ |
||||
doorClosed = FALSE; |
||||
if (configSensor && doorActUID != NULL_KEY) { |
||||
if (configAxisCenter) llSensorRepeat("", doorActUID, AGENT, doorActDist + 1.5, TWO_PI, 1.0); |
||||
else llSensorRepeat("", doorActUID, AGENT, doorActDist + 0.5, TWO_PI, 1.0); |
||||
llSetTimerEvent(0.0); |
||||
} |
||||
else if (configAutoClose > 0.0) { |
||||
llSetTimerEvent(configAutoClose); |
||||
} |
||||
} |
||||
|
||||
changed(integer change) |
||||
{ |
||||
if (change & CHANGED_INVENTORY) { |
||||
state loading; |
||||
} |
||||
} |
||||
|
||||
touch_end(integer total_number) |
||||
{ |
||||
if (configDistance > 0.0) { |
||||
if (llVecDist(llGetPos(), llDetectedPos(0)) <= configDistance) { |
||||
doorControl = TRUE; |
||||
state closing; |
||||
//if (doorClosed) door(llDetectedKey(0), llVecDist(llGetPos(), llDetectedPos(0))); |
||||
//else door(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
link_message(integer sender, integer num, string name, key id) |
||||
{ |
||||
if (llStringLength(configDouble) > 0 && name == configDouble) { |
||||
if (id == "door") { |
||||
if (doorControl) return; |
||||
//llOwnerSay("DEBUG: link_message:door: sender=" + (string)sender + ", num=" + (string)num); |
||||
if (num == TRUE) state closing; |
||||
} |
||||
else if (id == "lock") { |
||||
doorLock = num; |
||||
} |
||||
} |
||||
if (!accessLoaded) { |
||||
if (id == "clearkeys") { |
||||
Keys = []; |
||||
} |
||||
else if (id == "addkey") { |
||||
addKey(name, FALSE); |
||||
} |
||||
} else { |
||||
if (id == "getkeys") { |
||||
integer i; |
||||
|
||||
for (i = 0; i < llGetListLength(Keys); i++) { |
||||
llMessageLinked(sender, 1, llList2String(Keys, i), "addkey"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
no_sensor() |
||||
{ |
||||
llSensorRemove(); |
||||
state closing; |
||||
//door(); |
||||
} |
||||
|
||||
timer() |
||||
{ |
||||
llSetTimerEvent(0.0); |
||||
state closing; |
||||
//if (!doorClosed) door(); |
||||
} |
||||
} |
||||
|
||||
state closing |
||||
{ |
||||
state_entry() |
||||
{ |
||||
integer i; |
||||
rotation delta; |
||||
rotation rot = llGetLocalRot(); |
||||
vector pos = llGetLocalPos(); |
||||
vector size = llGetScale(); |
||||
float direction = configRotAngle; |
||||
|
||||
vector vPosOffset; |
||||
vector vPosRotOffset; |
||||
vector vPosOffsetDiff; |
||||
vector vPosRotDiff; |
||||
|
||||
//llOwnerSay("DEBUG: Door->Close"); |
||||
doorClosed = TRUE; |
||||
direction = -configRotAngle; |
||||
|
||||
llSetTimerEvent(0.0); |
||||
llSensorRemove(); |
||||
//llCollisionFilter("", NULL_KEY, TRUE); |
||||
if (doorControl) doorMsg(doorClosed, "door"); |
||||
if (configAxis == "x") delta = llEuler2Rot(<direction / configRotSteps, 0, 0> * DEG_TO_RAD); |
||||
else if (configAxis == "y") delta = llEuler2Rot(<0, direction / configRotSteps, 0> * DEG_TO_RAD); |
||||
else if (configAxis == "z") delta = llEuler2Rot(<0, 0, direction / configRotSteps> * DEG_TO_RAD); |
||||
|
||||
if (configAxisCenter) { |
||||
if (configAxisCenterAxis == "x") vPosOffset.x = (size.x / 2) * configAxisCenterDir; |
||||
else if (configAxisCenterAxis == "y") vPosOffset.y = (size.y / 2) * configAxisCenterDir; |
||||
else if (configAxisCenterAxis == "z") vPosOffset.z = (size.z / 2) * configAxisCenterDir; |
||||
} |
||||
|
||||
for (i =0; i < configRotSteps; i++) { |
||||
rot = delta * rot; |
||||
pos = llGetLocalPos(); |
||||
|
||||
if (configAxisCenter) { |
||||
vPosRotOffset = vPosOffset * delta; |
||||
vPosOffsetDiff = vPosOffset - vPosRotOffset; |
||||
vPosRotDiff = vPosOffsetDiff * llGetLocalRot(); |
||||
|
||||
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, llGetLocalPos() + (vPosOffset - vPosOffset * delta) * llGetLocalRot(), |
||||
PRIM_ROT_LOCAL, rot]); |
||||
} else { |
||||
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROT_LOCAL, rot]); |
||||
} |
||||
llSleep(configRotTime / configRotSteps); |
||||
} |
||||
|
||||
sound(soundClose); |
||||
doorControl = FALSE; |
||||
state closed; |
||||
} |
||||
} |
||||
|
||||
state opening |
||||
{ |
||||
state_entry() |
||||
{ |
||||
integer i; |
||||
rotation delta; |
||||
rotation rot = llGetLocalRot(); |
||||
vector pos = llGetLocalPos(); |
||||
vector size = llGetScale(); |
||||
float direction = configRotAngle; |
||||
|
||||
vector vPosOffset; |
||||
vector vPosRotOffset; |
||||
vector vPosOffsetDiff; |
||||
vector vPosRotDiff; |
||||
|
||||
//llOwnerSay("DEBUG: Door->Open"); |
||||
sound(soundOpen); |
||||
doorClosed = FALSE; |
||||
direction = configRotAngle; |
||||
|
||||
//llCollisionFilter("", NULL_KEY, FALSE); |
||||
if (doorControl) doorMsg(doorClosed, "door"); |
||||
if (configAxis == "x") delta = llEuler2Rot(<direction/configRotSteps, 0, 0> * DEG_TO_RAD); |
||||
else if (configAxis == "y") delta = llEuler2Rot(<0, direction/configRotSteps, 0> * DEG_TO_RAD); |
||||
else if (configAxis == "z") delta = llEuler2Rot(<0, 0, direction/configRotSteps> * DEG_TO_RAD); |
||||
|
||||
if (configAxisCenter) { |
||||
if (configAxisCenterAxis == "x") vPosOffset.x = (size.x / 2) * configAxisCenterDir; |
||||
else if (configAxisCenterAxis == "y") vPosOffset.y = (size.y / 2) * configAxisCenterDir; |
||||
else if (configAxisCenterAxis == "z") vPosOffset.z = (size.z / 2) * configAxisCenterDir; |
||||
} |
||||
|
||||
for (i =0; i < configRotSteps; i++) { |
||||
rot = delta * rot; |
||||
pos = llGetLocalPos(); |
||||
|
||||
if (configAxisCenter) { |
||||
vPosRotOffset = vPosOffset * delta; |
||||
vPosOffsetDiff = vPosOffset - vPosRotOffset; |
||||
vPosRotDiff = vPosOffsetDiff * llGetLocalRot(); |
||||
|
||||
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_POSITION, llGetLocalPos() + (vPosOffset - vPosOffset * delta) * llGetLocalRot(), |
||||
PRIM_ROT_LOCAL, rot]); |
||||
} else { |
||||
llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROT_LOCAL, rot]); |
||||
} |
||||
llSleep(configRotTime / configRotSteps); |
||||
} |
||||
|
||||
doorControl = FALSE; |
||||
state opened; |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue