///////////////////////////////////////////////////////////////////////////
//  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 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) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
vector wasUpperHemiSpherePoint(float radius) {
    float x = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
    float y = llPow(-1, 1 + (integer) llFrand(2)) * llFrand(radius*2);
    float z = llFrand(radius*2);
    if(llPow(x,2) + llPow(y,2) + llPow(z,2) <= llPow(radius,2))
        return <x, y, z>;
    return wasUpperHemiSpherePoint(radius);
}
 
moveTo(vector position) {
    llTargetRemove(targetID);
    targetID = llTarget(position, .8);
    llMoveToTarget(position, dampening);    
}
 
// track targets
integer targetID = 0;
// dampening of movement
float dampening = 0;
// stray from origin
float radius = 0;
// the origin of the movement
vector origin = ZERO_VECTOR;
// the listening handle
integer handle = 0;
 
default {
    listen(integer channel, string name, key id, string message) {
        llListenRemove(handle);
        dampening = (float)wasKeyValueGet("dampening", message);
        if(dampening == 0) dampening = 1;
        radius = (float)wasKeyValueGet("radius", message);
        if(radius == 0) radius = 1;
        origin = (vector)wasKeyValueGet("origin", message);
        if(origin == ZERO_VECTOR) origin = llGetPos();
        // start physics
        llSetStatus(STATUS_PHYSICS|STATUS_BLOCK_GRAB, TRUE);
        llVolumeDetect(TRUE);
        moveTo(origin + wasUpperHemiSpherePoint(radius));
    }
    at_target(integer tnum, vector targetpos, vector ourpos) {
        moveTo(origin + wasUpperHemiSpherePoint(radius));
    }
    collision_start(integer num) {
        moveTo(origin + wasUpperHemiSpherePoint(radius));
    }
    on_rez(integer num) {
        // bind to channel
        handle = llListen(num, "", "", "");
        // set temporary
        llSetLinkPrimitiveParamsFast(LINK_SET, [PRIM_TEMP_ON_REZ, TRUE]);
        // stop all physics
        llSetStatus(STATUS_PHYSICS|STATUS_BLOCK_GRAB_OBJECT, FALSE);
        llVolumeDetect(FALSE);
    }
}