commit 3dac7b989a9c7d4c32a04cfb31e465514a174bd7 Author: Eric Renfro Date: Wed Sep 30 13:01:30 2020 -0400 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/Simple Doors.lsl b/Simple Doors.lsl new file mode 100644 index 0000000..57867fb --- /dev/null +++ b/Simple Doors.lsl @@ -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( * 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( * 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; + } +} +