Table of Contents

Change Log

12 April 2013

  • Rewrote entire code.

18 December 2011

  • Fix for names / textures over 24 characters. Perhaps, in the future Linden can allow people to have names as long as Titin. I'm sure it can all be justified in some way or other.
  • Another fix to knock out the velocity mask in the particle flags. The textures should not rotate anymore.

4 December 2011

  • Marla Kanto pointed out it never changed avatars when selecting an avatar from the menu again. I figured out more than that was broken, the script simply did not work as it should. Now fixed.

Description

This is a generic dialog-based particle-texture poofer. It will allow you to select an avatar, a texture in the object's inventory and for how many seconds to poof the avatar with the texture. It uses the endless menus from giver in order to support an endless amount of loaded textures and avatars.

Setup

  1. Create a primitive.
  2. Drop this script inside it.
  3. Open the primitive and add textures to it.

You are set. Just click the primitive and use the menus to select your options.

Code

texture_particle_poofer.lsl
///////////////////////////////////////////////////////////////////////////
//  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) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
integer wasMenuIndex = 0;
list wasDialogMenu(list input, list actions, string direction) {
    integer cut = 11-wasListCountExclude(actions, [""]);
    if(direction == ">" &&  (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) {
        ++wasMenuIndex;
        jump slice;
    }
    if(direction == "<" && wasMenuIndex-1 >= 0) {
        --wasMenuIndex;
        jump slice;
    }
@slice;
    integer multiple = wasMenuIndex*cut;
    input = llList2List(input, multiple+wasMenuIndex, multiple+cut+wasMenuIndex);
    input = wasListMerge(input, actions, "");
    return input;
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
integer wasListCountExclude(list input, list exclude) {
    if(llGetListLength(input) == 0) return 0;
    if(llListFindList(exclude, (list)llList2String(input, 0)) == -1) 
        return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
    return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
list wasListMerge(list l, list m, string merge) {
    if(llGetListLength(l) == 0 && llGetListLength(m) == 0) return [];
    string a = llList2String(m, 0);
    if(a != merge) return [ a ] + wasListMerge(l, llDeleteSubList(m, 0, 0), merge);
    return [ llList2String(l, 0) ] + wasListMerge(llDeleteSubList(l, 0, 0), llDeleteSubList(m, 0, 0), merge);
}
 
list menu = [];
list keys = [];
string texture = "";
integer seconds = 0;
 
default
{
    touch_start(integer total_number) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llSensor("", "", AGENT, 96, TWO_PI);
    }
    sensor(integer num) {
        menu = [];
        keys = [];
        --num;
        do {
            menu += llGetSubString(llDetectedName(num), 0, 12);
            keys += llDetectedKey(num);
        } while(--num>-1);
 
        if(llGetListLength(menu) == 0) {
            llOwnerSay("Sorry, I could not find anybody around to poof");
            return;
        }
        state select_avatar;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state select_avatar {
    state_entry() {
        integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(comChannel, "", llGetOwner(), "");
        llDialog(llGetOwner(), "Please select an avatar to poof from the list below:\n", wasDialogMenu(menu, ["<= Back", "", "Next =>"], ""), comChannel);
        llSetTimerEvent(60);
    }
    listen(integer channel, string name, key id, string message) {
        if(message == "<= Back") {
            llSetTimerEvent(60);
            llDialog(id, "Please select an avatar to poof from the list below:\n",  wasDialogMenu(menu, ["<= Back", "", "Next =>"], "<"), channel);
            return;
        }
        if(message == "Next =>") {
            llSetTimerEvent(60);
            llDialog(id, "Please select an avatar to poof from the list below:\n",  wasDialogMenu(menu, ["<= Back", "", "Next =>"], ">"), channel);
            return;
        }
        integer i = llGetListLength(menu)-1;
        do {
            if(llSubStringIndex(llList2String(menu, i), message) == -1) jump continue;
            keys = (list)llList2Key(keys, i);
@continue;
        } while(--i>-1);
 
        menu = [];
        i = llGetInventoryNumber(INVENTORY_TEXTURE)-1;
        do {
            menu += llGetSubString(llGetInventoryName(INVENTORY_TEXTURE, i), 0, 12);
        } while(--i>-1);
        if(llGetListLength(menu) == 0) {
            llOwnerSay("Sorry, I have no textures loaded in my inventory. Drop some textures in my inventory first.");
            state default;
        }
        state select_texture;
    }
    timer() {
        llSetTimerEvent(0);
        llOwnerSay("Menu timeout...");
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state select_texture {
    state_entry() {
        integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(comChannel, "", llGetOwner(), "");
        llDialog(llGetOwner(), "Please select a texture to poof an avatar with:\n", wasDialogMenu(menu, ["<= Back", "", "Next =>"], ""), comChannel);
        llSetTimerEvent(60);
    }
    listen(integer channel, string name, key id, string message) {
        if(message == "<= Back") {
            llSetTimerEvent(60);
            llDialog(id, "Please select a texture to poof an avatar with:\n",  wasDialogMenu(menu, ["<= Back", "", "Next =>"], "<"), channel);
            return;
        }
        if(message == "Next =>") {
            llSetTimerEvent(60);
            llDialog(id, "Please select a texture to poof an avatar with:\n",  wasDialogMenu(menu, ["<= Back", "", "Next =>"], ">"), channel);
            return;
        }
        texture = message;
 
        menu = [];
        integer i = 2;
        do {
            menu += (string)i;
            i = i << 1;
        } while(i<1024);
        state select_seconds;
    }
    timer() {
        llSetTimerEvent(0);
        llOwnerSay("Menu timeout...");
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state select_seconds {
    state_entry() {
        integer comChannel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
        llListen(comChannel, "", llGetOwner(), "");
        llDialog(llGetOwner(), "Please select the number of seconds the avatar will be poofed:\n", menu, comChannel);
        llSetTimerEvent(60);
    }
    listen(integer channel, string name, key id, string message) {
        seconds = (integer)message;
        state poof;
    }
    timer() {
        llSetTimerEvent(0);
        llOwnerSay("Menu timeout...");
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state poof {
    state_entry() {
        llParticleSystem([12,texture,5,<.2,.2,.2>,6,<.45,.45,.45>,1,<1,1,1>,3,<1,1,1>,2,((float)1.0),4,((float)1.0),15,((integer)2),13,((float).8),7,((float)5.0),9,((integer)8),17,((float).5),18,((float).5),16,((float).5),22,(((float).4) * 3.14159274),23,(((float).0) * 3.14159274),8,<.0,.0,-.1>,0,((integer)335),20,llList2Key(keys,0)]);
        llSetTimerEvent(seconds);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llSetTimerEvent(0);
        llParticleSystem([]);
        state default;
    }
    timer() {
        llSetTimerEvent(0);
        llParticleSystem([]);
        state default;
    }
    on_rez(integer num) {
        llResetScript();
    }
}