Chat Painter

From Second Life Wiki
Revision as of 11:35, 30 May 2016 by Jenna Felton (talk | contribs) (Created page with "This script allows to change such properties as texture, color, transparency, fullbright, glow and shiny of one special face or all faces ot one special prim or all prims in t...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This script allows to change such properties as texture, color, transparency, fullbright, glow and shiny of one special face or all faces ot one special prim or all prims in the linkset. The commands are received via chat and can be sent by the owner themselves (e.g. using an emote) or a device belonging to them, like a HUD. The script for the HUD or the emote are not provided, though.

The script supports up to 256 prims linkset, although changing "all prims" at once is not reccomended for large linksets because the changes will not be visible due capping the updates (i think its an interest list problem and not a problem of this script.)

Usage

Put the script into the linkset under control. It will scan the linkset for the prim names and then tell it is ready.

To activate the script, touch the linkset at any prim. It will start the listen and tell the command to close the listen.

To reset the script, touch again and hold the mouse button for about 2 seconds (long touch.)


Commands

TBC


Configuration

TBC

Painter Script

//----------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// You may ONLY redistribute this program with copy, mod and transfer
// permissions and ONLY if this preamble is not removed.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
//
// Script: ChatPainter
//
// Allows to change the texture and collor properties of named faces
// of named prims in a linkset by using chat commands.
//
//----------------------------------------------------------------------------
// Version:       1.0.0
// Contributors:  Jenna Felton - initial release
//----------------------------------------------------------------------------

// --- [ SETTINGS ] ----------------------------------------------------------

// Channel for chat commands
integer CHANNEL    = 1901;

// Face names and numbers. Format: Name, number, name, number...
// * Every face name must appear once, i.e. address one number.
// * More than one face name can address same face number.
// * Face names must use lower-case letters.
list    FACE_NUMS  = [
    // these names we can use for the one group of prims
    "top",    0,
    "front",  1,
    "right",  2,
    "back",   3,
    "left",   4,
    "bottom", 5,
    
    // and these names for the other group of prims
    "alpha",  0,
    "beta",   1,
    "gamma",  2,
    
    // this is also possible, but for addressing ALL_SIDES
    // we better use the special face name "each" instead
    "omega", -1 
    ];

// --- [ SETTINGS END ]  -----------------------------------------------------

key     kOwner     = NULL_KEY;
integer gPrims     = 0;

integer hListen    = 0;

list    lLinks     = [];

// --- -----------------------------------------------------------------------

// updates shiny on given face(s) of given link (only single prim)
// without touching the bump of the faces

changeShiny(integer link, integer face, integer shiny) {
    // result : [ integer shiny, integer bump ] per face.
    list bumps = llGetLinkPrimitiveParams(link, [PRIM_BUMP_SHINY, face]);
    
    if (face != ALL_SIDES) {
        llSetLinkPrimitiveParams(link,
            [PRIM_BUMP_SHINY, face, shiny, llList2Integer(bumps, 1)]);
    }
    else {
        integer num = llGetLinkNumberOfSides(link);
        for (face = 0 ; face < num ; face++) {
            llSetLinkPrimitiveParams(link,
                [PRIM_BUMP_SHINY, face, shiny, llList2Integer(bumps, face*2+1)]);
        }
    }
}

// --- -----------------------------------------------------------------------
 
default {
    // --- administration ----------------------------------------------------
    
    state_entry() {
        kOwner  = llGetOwner();
        gPrims  = llGetNumberOfPrims();
        
        // fill up the dictionary
        integer link;
        integer links = llGetNumberOfPrims();
        lLinks        = [];
        for (link = 0 ; link <= links ; link++) {
            lLinks += llToLower(llGetLinkName(link));
        }

        llOwnerSay("Painter started. Touch to open listen, long touch to reset");
        
        //// 256 prims, 63 chars -> 52 kB used
        //// 256 prims, 8 chars  -> 23 kB used
        //// 1 prim,    63 chars -> 14 kB used
        //llOwnerSay("state_entry: used "+(string)llGetUsedMemory()+" Bytes");
    }
    
    on_rez(integer param) {
        llResetScript();
    }

    touch_start(integer number) {
        if (llDetectedKey(0) != kOwner) return;
        llResetTime();
    }

    touch_end(integer number) {
        if (llDetectedKey(0) != kOwner) return;

        if (llGetTime() > 1.5) llResetScript();
        
        else if (hListen == 0) {
            hListen = llListen(CHANNEL, "", NULL_KEY, "");
            llOwnerSay("listen open (/"+(string)CHANNEL+"close to close again)");
        }
    }

    changed(integer change) {
        if (change & CHANGED_LINK) llResetScript();
    }
    
    // --- chat interface ----------------------------------------------------

    listen(integer channel, string name, key id, string message) {
        if (llGetOwnerKey(id) != kOwner) return;
        message = llToLower(llStringTrim(message, STRING_TRIM));

        // 1. Supercommand "close"
        
        if (message == "close") {
            llListenRemove(hListen);
            hListen = 0;
            llOwnerSay("listen closed (touch to open again)");
            return;
        }

        // 2. Regular command "prim face commandlist"
        //    while prim is "set", "all" or a prim number or name.
        //                  Omitted for a single prim build
        //    and   face is "each", face number or face name from da list
        
        list    cmds = llParseString2List(message, [" ", ",", ";"], []);
        integer link;
        integer face;
        if (gPrims > 1) {
            name     = llList2String(cmds, 0);  // prim
            message  = llList2String(cmds, 1);  // face
            cmds     = llDeleteSubList(cmds, 0, 1);
        }
        else {
            name     = "set";                   // prim
            message  = llList2String(cmds, 0);  // face
            cmds     = llDeleteSubList(cmds, 0, 0);
        }

        // a. testing face is faster

        if      (message == "each") face = ALL_SIDES;
        else if (message == "0")    face = 0;
        else {
            face = (integer)message;
            if (face == 0) {
                face  = llListFindList(FACE_NUMS, [message]);
                if (face < 0) {
                    llOwnerSay("No such face: '"+message+"'");
                    return;
                }
                else {
                    face = llList2Integer(FACE_NUMS, face+1);
                }
            }
        }

        // b. testing target prim "set", "all" or number
        
        if      (name == "set") link  = LINK_THIS;
        else if (name == "all") link  = LINK_SET;
        else if (name == "0")   link  = 0;
        else {
            link = (integer)name;
            if (link == 0) {
                link = llListFindList(lLinks, [name]);
                if (link < 0) {
                    llOwnerSay("No such link: '"+name+"'");
                    return;
                }
            }
        }

        // 3. processing commandlist
        //    List : color A7B8C9, fullb Y/N/1/0, shiny num,
        //           image key, glow value, alpha value
        //    

        while (cmds != []) {
            name     = llList2String(cmds, 0);  // command
            message  = llList2String(cmds, 1);  // parameter
            cmds     = llDeleteSubList(cmds, 0, 1);

            // color hex-value
            if (name == "color") {
                message   = "0x"+message;
                channel   = (integer)message;

                integer r = (channel>>16)&0xFF;
                integer g = (channel>>8)&0xFF;
                integer b = channel&0xFF;

                llSetLinkColor(link,
                    <(float)r, (float)g, (float)b>/255.0, face);
            }

            // alpha float
            else if (name == "alpha") {
                float val = (float)message;
                if      (val < 0.0) val = 0.0;
                else if (val > 1.0) val = 1.0;
                
                llSetLinkAlpha(link, val, face);
            }

            // glow float
            else if (name == "glow") {
                float val = (float)message;
                if      (val < 0.0) val = 0.0;
                else if (val > 1.0) val = 1.0;
                
                llSetLinkPrimitiveParamsFast(link,
                    [PRIM_GLOW, face, val]);
            }

            // shiny 0..3
            else if (name == "shiny") {
                channel = (integer)message;
                if      (channel < 0) channel = 0;
                else if (channel > 3) channel = 3;

                // Work on entire linkset
                if (link == LINK_SET) {
                    for (link = 1 ; link <= gPrims ; link++) {
                        changeShiny(link, face, channel);
                    }
                }

                // Only a single prim
                else {
                    changeShiny(link, face, channel);
                }
            }

            // fullb boolean
            else if (name == "fullb") {
                if      (message == "y") channel = 1;
                else if (message == "n") channel = 0;
                else                     channel = (integer)message;
                
                llSetLinkPrimitiveParamsFast(link,
                    [PRIM_FULLBRIGHT, face, channel]);
            }

            // image key
            else if (name == "image") {
                llSetLinkTexture(link, message, face);
            }

            else llOwnerSay("No such command: '"+name+"'");

        }
    }
}

// --- ------------------------------------------