/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueGet(string k, string data) { if(llStringLength(data) == 0) return ""; if(llStringLength(k) == 0) return ""; list a = llParseStringKeepNulls(data, ["&", "="], []); integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); if(i != -1) return llList2String(a, 2*i+1); return ""; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueSet(string k, string v, string data) { if(llStringLength(k) == 0) return ""; if(llStringLength(v) == 0) return ""; if(llStringLength(data) == 0) return k + "=" + v; integer i = llListFindList( llList2ListStrided( llParseString2List(data, ["&", "="], []), 0, -1, 2 ), [ k ]); if(i != -1) return llDumpList2String( llListReplaceList( llParseString2List(data, ["&"], []), [ k + "=" + v ], i, i), "&"); return data + "&" + k + "=" + v; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// LID(key id) { if(id != NULL_KEY && llGetAttached() != 0) { llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", (string)((integer)wasKeyValueGet("login", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))+1), llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); llResetScript(); } llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", "-1", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); } moveTo(vector target, integer bb) { llStopMoveToTarget(); llTargetRemove(moveTarget); vector pointTo = target - llGetPos(); llOwnerSay("@setrot:" + (string)llAtan2(pointTo.x, pointTo.y) + "=force"); moveTarget = llTarget(target, 2 + bb); llMoveToTarget(target, 2); } key master = NULL_KEY; integer hasRLV = FALSE; integer moveTarget = 0; default { state_entry() { // LID™ reasoning - http://grimore.org/fuss:lsl#log-in_detection_with_attachments // if LID™, then login = 1 // else login = 0 - script running | parameter undefined if((integer)wasKeyValueGet("login", llGetObjectDesc()) > 0) { llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", "0", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); state check; return; } llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", "0", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); state check; } // LID™ reasoning - http://grimore.org/fuss:lsl#log-in_detection_with_attachments // order: on_rez -> attach // // if object attached, then login := login+1 // else login := -1 attach(key id) { // attached if(id != NULL_KEY && llGetAttached() != 0) { llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", (string)((integer)wasKeyValueGet("login", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))+1), llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); // Reset script for llGetCreator() bugture. llResetScript(); } // detached llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", "-1", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); } // login = 1 after object attached // = -1 after object detached } state check { state_entry() { llSetTimerEvent(25); integer _comChannel = 10+(integer)llFrand(10); llListen(_comChannel, "", llGetOwner(), ""); llOwnerSay("@version=" + (string)_comChannel); } timer() { llSetTimerEvent(0); // Do not pester the avatar; you are here if you don't have RLV. hasRLV = FALSE; state tellkey; } listen(integer channel, string name, key id, string message) { llSetTimerEvent(0); hasRLV = TRUE; state tellkey; } changed(integer change) { llResetScript(); } on_rez(integer num) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } } state tellkey { state_entry() { integer comChannel = (integer)("0x8" + llGetSubString(llGetCreator(), 0, 6)); llListen(comChannel+1, "", "", ""); llSetTimerEvent(1); } listen(integer channel, string name, key id, string messsage) { // alarm llSetTimerEvent(1); if(messsage == "sync") { master = id; llWhisper(channel, "sync="+(string)llGetKey()); return; } if(messsage == "stop") state stop; } timer() { if(master) return; llResetScript(); } changed(integer change) { llResetScript(); } on_rez(integer num) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } } state stop { state_entry() { if(hasRLV == FALSE) return; llSetTimerEvent(1); } timer() { vector pos = llList2Vector(llGetObjectDetails(master, [OBJECT_POS]), 0); if(pos == ZERO_VECTOR) llResetScript(); integer distance = (integer)llVecDist(pos, llGetPos()); if(distance > 65) llResetScript(); if(distance < 5) { llStopMoveToTarget(); llTargetRemove(moveTarget); return; } moveTo( pos, (integer)(llVecDist(llList2Vector(llGetBoundingBox(master), 1), llList2Vector(llGetBoundingBox(master), 0))/2.0) ); } changed(integer change) { llResetScript(); } on_rez(integer num) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } }