/////////////////////////////////////////////////////////////////////////// // 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))]); } key prim = NULL_KEY; /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// 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 tellkey; return; } llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, wasKeyValueSet("login", "0", llList2String(llGetLinkPrimitiveParams(2, [PRIM_DESC]), 0))]); state tellkey; } // 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 tellkey { state_entry() { integer comChannel = (integer)("0x8" + llGetSubString(llGetCreator(), 0, 6)); llListen(comChannel+1, "", "", ""); llSetTimerEvent(1); } timer() { integer comChannel = (integer)("0x8" + llGetSubString(llGetCreator(), 0, 6)); llWhisper(comChannel+1, "sync"); } listen(integer channel, string name, key id, string messsage) { prim = (key)wasKeyValueGet("sync", messsage); if(prim == NULL_KEY) return; llWhisper(channel, "stop"); state stop; } 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() { llParticleSystem( [ PSYS_PART_START_SCALE, <.15,.15,0>, PSYS_PART_END_SCALE, <.15,.15,0>, PSYS_SRC_TEXTURE, "300defc4-739c-6d31-3f51-3ade4185c544", PSYS_SRC_BURST_PART_COUNT, 8192, PSYS_SRC_BURST_RATE, 0.001, PSYS_PART_MAX_AGE, 1, PSYS_SRC_MAX_AGE, 0, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP, PSYS_SRC_ACCEL,(vector) <0,0,-.01>, PSYS_SRC_TARGET_KEY,(key) prim, PSYS_PART_FLAGS, PSYS_PART_EMISSIVE_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK | PSYS_PART_FOLLOW_SRC_MASK | PSYS_PART_TARGET_POS_MASK ] ); llSetTimerEvent(1); } timer() { vector target = llList2Vector(llGetObjectDetails(prim, [OBJECT_POS]), 0); if(target == ZERO_VECTOR) llResetScript(); vector origin = llGetPos(); if(llVecDist(target, origin) < 5) return; float dΔ=llVecDist(<target.x,target.y,0>,<origin.x,origin.y,0>); float valSin = 9.81/llPow(3.5, 2); /* Attempt low angle. */ if(valSin < -1 || valSin > 1) return; /* Won't even lift the projectile off the ground. Abort. */ llApplyImpulse(llVecNorm(<1,0,0>*llRotBetween(<1,0,0>,llVecNorm(<target.x-origin.x,target.y-origin.y, dΔ*llTan((90-RAD_TO_DEG*llAsin(valSin)/2) * DEG_TO_RAD) + llFabs(target.z-origin.z)>)))*2.25, FALSE); } 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); } }