paul.lsl
///////////////////////////////////////////////////////////////////////////
//  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) 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) 2011 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
vector wasRectanglePoint(float x, float y) {
    llSleep(1);
    x = llPow(-1, 1 + (integer)llFrand(2)) * llFrand(x);
    llSleep(1);
    y = llPow(-1, 1 + (integer)llFrand(2)) * llFrand(y);
    return _iPos + <x, y, 0>;
}
 
integer _targetID = 0;
moveTo(vector position) {
    llTargetRemove(_targetID);
    _targetID = llTarget(position, .8);
    llLookAt(position, .6, .6);
    llMoveToTarget(position, 10);    
}
 
// Set this to the centre or origin point from where all  
// random points will be picked.
vector _iPos = ZERO_VECTOR;
 
default {
    sensor(integer num) {
        llParticleSystem( [  
            PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE, 
            PSYS_SRC_BURST_PART_COUNT,(integer) 5,   // adjust for beam strength,
            PSYS_SRC_BURST_RATE,(float) .05,          
            PSYS_PART_MAX_AGE,(float)  .6,            
            PSYS_SRC_BURST_SPEED_MIN,(float).5,        
            PSYS_SRC_BURST_SPEED_MAX,(float) .5,      
            PSYS_PART_START_SCALE,(vector) <.02,.02,0>, 
            PSYS_PART_END_SCALE,(vector) <.04,.04,0>,   
            PSYS_PART_START_COLOR,(vector) <0,1,0>,  
            PSYS_PART_END_COLOR,(vector) <0,.2,0>,   
            PSYS_PART_START_ALPHA,(float)0.5,          
            PSYS_PART_END_ALPHA,(float)0.00,
            PSYS_SRC_TARGET_KEY, llDetectedKey(0),        
            PSYS_PART_FLAGS,
                PSYS_PART_INTERP_COLOR_MASK   
                                | PSYS_PART_INTERP_SCALE_MASK   
                                | PSYS_PART_EMISSIVE_MASK   
                                | PSYS_PART_FOLLOW_VELOCITY_MASK
                                                  // After-effect & Influence Options:
                              // | PSYS_PART_WIND_MASK            
                             // | PSYS_PART_BOUNCE_MASK          
                             // | PSYS_PART_FOLLOW_SRC_MASK     
                                | PSYS_PART_TARGET_POS_MASK     
                             // | PSYS_PART_TARGET_LINEAR_MASK                  
        ] );
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llDie();
    }
    at_target(integer tnum, vector targetpos, vector ourpos) {
        if(tnum != _targetID) return;
        moveTo(wasRectanglePoint(.3137, .3137));
    }
    listen(integer channel, string name, key id, string message) {
        if(llGetOwner() != llGetOwnerKey(id)) return;
        if(wasKeyValueGet("die", message) != llGetCreator()) return;
        llDie();
    }
    on_rez(integer num) {
        if(num == 0 && llGetOwner() != llGetCreator()) llDie();
        llListen(num, "[WaS-K] Fishulus", "", "");
        llSetObjectName(wasKeyValueSet("Paul", llGetCreator(), llGetObjectName()));
        llSetLinkPrimitiveParamsFast(LINK_SET, [PRIM_TEMP_ON_REZ, TRUE]);
        llSetText("|^ /\\ |_| |_", <0,1,1>, 1);
        _iPos = llGetPos();
        llVolumeDetect(TRUE);
        llSetStatus(STATUS_PHYSICS|STATUS_BLOCK_GRAB, TRUE);
        llSensorRepeat("Maggie", "", SCRIPTED|ACTIVE, .5, TWO_PI, 1);
        moveTo(wasRectanglePoint(.3137, .3137));
    }
}