/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2021 - 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: CC BY 2.0 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueEncode(list data) { integer i = llGetListLength(data); if (i % 2 != 0 || i == 0) return ""; --i; do { data = llListInsertList( llDeleteSubList( data, i-1, i ), [ llList2String(data, i-1) + "=" + llList2String(data, i) ], i-1 ); i -= 2; } while(i > 0); return llDumpList2String(data, "&"); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// vector wasCirclePoint(float radius) { float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2); if(llPow(x,2) + llPow(y,2) <= llPow(radius,2)) return <x, y, 0>; return wasCirclePoint(radius); } // for notecard reading integer line = 0; // key-value data will be read into this list list tuples = []; default { state_entry() { if(llGetInventoryType(llGetInventoryName(INVENTORY_NOTECARD, 0)) != INVENTORY_NOTECARD) { llSay(DEBUG_CHANNEL, "Sorry, could not find a configuration notecard inside the object."); return; } llGetNotecardLine( llGetInventoryName( INVENTORY_NOTECARD, 0 ), line ); } dataserver(key id, string data) { if(data == EOF) state spawn; // invariant, length(tuples) % 2 == 0 // Skip empty lines. if(data == "") { llGetNotecardLine( llGetInventoryName( INVENTORY_NOTECARD, 0 ), ++line ); return; } integer i = llSubStringIndex(data, "#"); if(i != -1) data = llDeleteSubString(data, i, -1); list o = llParseString2List(data, ["="], []); // get rid of starting and ending quotes string k = llDumpList2String( llParseString2List( llStringTrim( llList2String( o, 0 ), STRING_TRIM), ["\""], [] ), "\""); string v = llDumpList2String( llParseString2List( llStringTrim( llList2String( o, 1 ), STRING_TRIM), ["\""], [] ), "\""); if(k == "" || v == "") { llGetNotecardLine( llGetInventoryName( INVENTORY_NOTECARD, 0 ), ++line ); return; } tuples += k; tuples += v; llGetNotecardLine( llGetInventoryName( INVENTORY_NOTECARD, 0 ), ++line ); } changed(integer change) { if(change & CHANGED_INVENTORY) { llResetScript(); } } on_rez(integer num) { llResetScript(); } } state spawn { state_entry() { llSetTimerEvent( 1.0/llList2Float( tuples, llListFindList( tuples, [ "rate" ] )+1 ) ); llSensorRepeat("", NULL_KEY, AGENT, 0.1, 0.1, 1.0/llList2Float( tuples, llListFindList( tuples, [ "rate" ] )+1 ) ); } no_sensor() { llRezObject( llGetInventoryName( INVENTORY_OBJECT, (integer)llFrand( llGetInventoryNumber(INVENTORY_OBJECT) ) ), llGetPos() + wasCirclePoint( llList2Float( tuples, llListFindList( tuples, [ "radius" ] )+1 ) ), ZERO_VECTOR, ZERO_ROTATION, (integer)( "0x8" + llGetSubString(llGetKey(), 0, 6) ) ); } timer() { llRegionSay( (integer)("0x8" + llGetSubString(llGetKey(), 0, 6)), wasKeyValueEncode(tuples) ); } changed(integer change) { if(change & CHANGED_INVENTORY) { llResetScript(); } } on_rez(integer num) { llResetScript(); } }