/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2014 - 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) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// moveTo(vector target, integer bb, key agent) { llStopMoveToTarget(); llTargetRemove(moveTarget); vector mePos = llGetPos(); vector pointTo = target - mePos; llOwnerSay("@setrot:" + (string)llAtan2(pointTo.x, pointTo.y) + "=force"); moveTarget = llTarget(target, 2 + bb); float dampening = llVecDist(target, mePos)/3.20; if(llGetAgentInfo(agent) & AGENT_ALWAYS_RUN) { dampening = llVecDist(target, mePos)/5.13; jump move; } @move; if(dampening < 0.045) dampening = 0.045; llMoveToTarget(target, dampening); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// wasTellOwner(string type, string message) { llOwnerSay("⎣" + type + "⎤: " + message + "."); } /////////////////////////////////////////////////////////////////////////// // 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) 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 wasKeyValueDelete(string k, string data) { if(llStringLength(data) == 0) return ""; if(llStringLength(k) == 0) return ""; integer i = llListFindList( llList2ListStrided( llParseString2List(data, ["&", "="], []), 0, -1, 2 ), [ k ]); if(i != -1) return llDumpList2String( llDeleteSubList( llParseString2List(data, ["&"], []), i, i), "&"); return data; } /////////////////////////////////////////////////////////////////////////// // 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))]); } string criteria = ""; key uuid = NULL_KEY; 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 on_rez(integer num) { llResetScript(); } changed(integer change) { llResetScript(); } } state check { state_entry() { // alarm for seekng RLV llSetTimerEvent(25); integer channel = 10+(integer)llFrand(10); llListen(channel, "", llGetOwner(), ""); llOwnerSay("@version=" + (string)channel); } timer() { llSetTimerEvent(0); // alarm triggered, we don't have RLV wasTellOwner("follow", "This gizmo requires a RLV-enabled viewer."); return; } listen(integer channel, string name, key id, string message) { llSetTimerEvent(0); // we have RLV state seek; } on_rez(integer num) { llResetScript(); } changed(integer change) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } } state seek { state_entry() { uuid = (key) wasKeyValueGet("follow", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0)); if(uuid != "") state follow; if(criteria != "") { llSensorRepeat("", "", AGENT, 65, TWO_PI, 1); // alarm for searching agent matching criteria llSetTimerEvent(5); } llListen(0, "", llGetOwner(), ""); } listen(integer channel, string name, key id, string message) { list cmd = llParseString2List(message, [" "], []); if(llList2String(cmd, 0) != "@follow") { cmd = []; return; } criteria = llList2String(cmd, 1); llSensorRepeat("", "", AGENT, 65, TWO_PI, 1); // alarm for searching agent matching criteria llSetTimerEvent(5); } timer() { wasTellOwner("follow", "Could not find avatar to follow..."); llResetScript(); } sensor(integer num) { --num; do { list name = llParseString2List(llDetectedName(num), ["."], []); do { string nib = llList2String(name, 0); if(llSubStringIndex(llToLower(nib), llToLower(criteria)) != -1) { wasTellOwner("follow", "Target agent found..."); uuid = llDetectedKey(num); llSetLinkPrimitiveParamsFast( 2, [PRIM_DESC, wasKeyValueSet( "follow", (string)uuid, llList2String( llGetLinkPrimitiveParams( 2, [PRIM_DESC] ), 0 ) ) ] ); criteria = ""; wasTellOwner("follow", "Starting follow..."); state follow; } name = llDeleteSubList(name, 0, 0); } while(llGetListLength(name) != 0); } while(--num>-1); } on_rez(integer num) { llResetScript(); } changed(integer change) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } } state follow { state_entry() { llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS); llSensorRepeat("", uuid, AGENT, 65, TWO_PI, 1); llListen(0, "", llGetOwner(), ""); } listen(integer channel, string name, key id, string message) { list cmd = llParseString2List(message, [" "], []); if(llList2String(cmd, 0) != "@follow" && llList2String(cmd, 0) != "@unfollow") { cmd = []; return; } if(llList2String(cmd, 0) == "@unfollow") { wasTellOwner("follow", "Stopping follow..."); } llSetLinkPrimitiveParamsFast( 2, [PRIM_DESC, wasKeyValueDelete( "follow", llList2String( llGetLinkPrimitiveParams( 2, [PRIM_DESC] ), 0 ) ) ] ); if(llList2String(cmd, 0) == "@follow") { criteria = llList2String(cmd, 1); llSetTimerEvent(0); state seek; } llResetScript(); } run_time_permissions(integer perm) { if(perm & PERMISSION_TAKE_CONTROLS) { llTakeControls( CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT | CONTROL_UP | CONTROL_DOWN | CONTROL_LBUTTON | CONTROL_ML_LBUTTON, TRUE, TRUE); return; } wasTellOwner("follow", "Could not get control permissions. Restarting script."); llResetScript(); } sensor(integer num) { --num; do { vector pos = llDetectedPos(num); if(llVecDist(pos, llGetPos()) < 5) { llStopMoveToTarget(); llTargetRemove(moveTarget); return; } if(llGetAgentInfo(uuid) & AGENT_IN_AIR) return; moveTo( pos, (integer)(llVecDist(llList2Vector(llGetBoundingBox(uuid), 1), llList2Vector(llGetBoundingBox(uuid), 0))/2.0), uuid ); return; } while(--num>-1); } at_target(integer tnum, vector targetpos, vector ourpos) { llStopMoveToTarget(); llTargetRemove(moveTarget); } control(key id, integer level, integer edge) { // while key is held down, don't move the avatar if(level & ~edge == 0) return; llStopMoveToTarget(); llTargetRemove(moveTarget); llReleaseControls(); llSetTimerEvent(0); state move; } on_rez(integer num) { llResetScript(); } changed(integer change) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } } state move { state_entry() { llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS); } run_time_permissions(integer perm) { if(perm & PERMISSION_TAKE_CONTROLS == 0) { wasTellOwner("follow", "Could not get control permissions. Restarting script."); llResetScript(); } llTakeControls( CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT | CONTROL_UP | CONTROL_DOWN | CONTROL_LBUTTON | CONTROL_ML_LBUTTON, TRUE, TRUE); } control(key id, integer level, integer edge) { // alarm llSetTimerEvent(1); } timer() { llSetTimerEvent(0); llReleaseControls(); state follow; } on_rez(integer num) { llResetScript(); } changed(integer change) { llResetScript(); } // LID™ - http://grimore.org/fuss:lsl#log-in_detection_with_attachments attach(key id) { LID(id); } }