Jump to content
Sign in to follow this  
Lymirah Gardner

Appearing and Disappearing Objects/Linksets on Chat Command

Recommended Posts

This was probably the first moderately complicated script I wrote.  It stems from my burlesque performances and my desire to demystify some of the scripting abilities for other performers.  In other words, I wanted to give them a powerful, somewhat easy-to-use script that might enable them to achieve effects they could not otherwise realize without a deeper (or any) knowledge of LSL.  I have no idea if it was successful with this goal, but I do want to share it with others.

The script toggles appearance (hide/show) of object1 with a command on a so-called "common" channel.  Enables control of multiple such objects on a single channel.  Commands are not case-sensitive.  Initial state of object1 (hidden/shown) set by global variable.  Enables fading in/out of object1. Assumes even change of alpha setting over the duration.  Can have different fade in/fade out speeds.  Chat commands entered during (in the middle of) a fade in or fade out will not be acted on.  Can use a single command to toggle multiple objects/linksets (each having their own version of the script), such as fading out object1 while fading in object2.  Everything is controlled/set via global variables.

The script is purposefully written to be a bit bloated (bound checking, redundancy on achieving the desired alpha, etc.).  Remember - it was written for the non-scripter and for use in a temporary setting (a burlesque performance.  If using this as a scripter, I encourage you to modify it and remove some of the bloat - it should be recognizable (the user function "checkgvar()" is pure bound-checking; the user-function "setcvar()" can be reduced to eliminate the bound-checking; better yet the entire script can be tailored to the specific use, removing unused parts).

The biggest extensible point for this script is to enable per-link number control so that it can operate within a linkset by fading in/out only parts of the linkset.  While I've put together such a version for my personal use, I decided only to release the simple-user version below.  A scripter should be able to tailor this to per-link number control.  If you want any assistance with this, hit me up in SL (notecard if offline, IM if online) or send me a private message (and hope I remember to sign in soon and see it).

I've tested the script for the identified functionality and it appears to work correctly.  (Believe me, I tried to troubleshoot this sucker as best I could.)  If anyone has any recommendations, either for the existing code or additional features, please let me know!

 

/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Object Appearance Script by Lymirah Gardner, Version 1.2b, 12 March 2012
// Channel Commands for Having an Object/Linkset Appear and/or Disappear
//
//<----------------------- STRETCH YOUR WINDOW THIS WIDE FOR EASY READING ------------------------>//
//
// Script for object1/linkset1 (referred to herein as "object1").
// Works for a single object or an entire linkset.
//
// Toggles appearance (hide/show) of object1 with a command on a so-called "common" channel.
// Enables control of multiple such objects on a single channel.  Commands are not case-sensitive.
// Initial state of object1 (hidden/shown) set by global variable.
// Enables fading in/out of object1.  Assumes even change of alpha setting over the duration.
// Can have different fade in/fade out speeds.
// Chat commands entered during (in the middle of) a fade in or fade out will not be acted on.
//
// Currently set up only for owner control.
// Extensible to per-link item (e.g., per-prim) control.
//
// OPERATION:
//
//     Type this in local:    To do this:                                       Example:
//     ---------------------------------------------------------------------------------------
//     /CHANNEL commhide      Hide object 1 while it is shown.                  /42 object2
//     /CHANNEL commshow      Show object 1 while it is hidden.                 /42 object1
//     /CHANNEL commreset     Reset script while object1 is hidden or shown.    /42 reset
//
// FIRST EXAMPLE WITH TWO OBJECTS:
//
// Set object1 to show at the start, hide with command "object2" and show with command "object1".
// Set object2 to hide at the start, show with command "object2" and hide with command "object1".
// At start, object1 is shown and object2 is hidden.
// When you type "/42 object2" in local chat, object1 will hide and object2 will show.
// When you type "/42 object1" in local chat, object1 will show and object2 will hide.
// When you type "/42 reset" in local chat, both will revert to their initial states.
//
// SECOND EXAMPLE WITH TWO OBJECTS:
//
// Assume you changed the first example above such that object2 does not hide again.
//     This is accomplished by changing a variable (HIDEOBJ_ON = 0) in the script for object2.
//     The script for object1 remains the same since its operation is the exact same.
// When you type "/42 object2" in local chat, object1 will hide and object2 will show.
// When you type "/42 object1" in local chat, object1 will show.  Object2 will remain showing.
//     (This command now has no effect on the state of object2 – whether it is shown or hidden.)
// When you type "/42 reset" in local chat, both will revert to their initial states.
//
// Note that in all of the above examples, the commands will only have an effect if the respective
// object is in the opposite state.  That is, the command to hide object1 will have no effect on
// object1 if object1 is already hidden when the command is given.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Please feel free to share this script.  It's meant for anyone and everyone!  All I ask is that
// you don't sell the script on its own or as part of any package, objects or products.  It's
// provided for free - please keep it that way!  Please also keep this title box.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////////
//                                      GLOBAL VARIABLES
/////////////////////////////////////////////////////////////////////////////////////////////////////

//***Main Controls***

integer CHANNEL = 42;               //set listen channel number:  CHANNEL > 0
integer HIDE_START = 0;             //toggles whether object1 is shown or hidden at start:
                                    //0 = shown, 1 = hidden
string commreset = "reset";         //chat command to reset script


//***Show Object Attributes***

integer SHOWOBJ_ON = 1;             //toggles whether object is shown on command: 0 = off, 1 = on
string commshow = "object2";        //chat command to show object1
integer FADEIN_ON = 0;              //toggles fading of object on show: 0 = off, 1 = on
integer FADEIN_SPD = 1;             //speed of fade in: 0 = custom, 1 = slow, 2 = medium, 3 = fast
                                    //slow:    10 steps over 5 seconds
                                    //medium:   6 steps over 3 seconds
                                    //fast:     5 steps over 1 second


//***Hide Object Attributes***

integer HIDEOBJ_ON = 1;             //toggles whether object is hidden on command: 0 = off, 1 = on
string commhide = "object1";        //chat command to hide object1
integer FADEOUT_ON = 0;             //toggles fading of object on hide: 0 = off, 1 = on
integer FADEOUT_SPD = 1;            //speed of fade out: 0 = custom, 1 = slow, 2 = medium, 3 = fast
                                    //slow:    10 steps over 5 seconds
                                    //medium:   6 steps over 3 seconds
                                    //fast:     5 steps over 1 second


/////////////////////////////////////////////////////////////////////////////////////////////////////
//                                        CUSTOM FADING
/////////////////////////////////////////////////////////////////////////////////////////////////////

//***Change these variables if custom fade in is used.***

float SHOW_CALPHA = 1.0;            //alpha of object when shown: 1.0 = normal/fully shown
                                    //0.0 < SHOW_CALPHA <= 1.0 and HIDE_CALPHA < SHOW_CALPHA
integer FADEIN_CSTEPS = 20;         //custom fade in: number of steps/increments
                                    //FADEIN_CTEPS >= 1
float FADEIN_CTIME = 10.0;          //custom fade in: time for fade (in seconds)
                                    //FADEIN_CTIME >= 1.0


//***Change these variables if custom fade out is used.***

float HIDE_CALPHA = 0.0;            //alpha of object when hidden: 0.0 = normal/fully hidden
                                    //0.0 <= HIDE_CALPHA < 1.0 and HIDE_CALPHA < SHOW_CALPHA
integer FADEOUT_CSTEPS = 20;        //custom fade out: number of steps/increments
                                    //FADEOUT_CTEPS >= 1
float FADEOUT_CTIME = 10.0;         //custom fade out: time for fade (in seconds)
                                    //FADEOUT_CTIME >= 1.0

//For custom alpha settings, set both custom alphas (SHOW_CALPHA and HIDE_CALPHA)
//even if only using one of custom fade in or custom fade out.

//Even if only using one of custom fade in or custom fade out, alpha settings are pulled
//from both custom alpha settings (SHOW_CALPHA and HIDE_CALPHA).


/////////////////////////////////////////////////////////////////////////////////////////////////////
//               DON'T CHANGE ANYTHING BELOW THIS UNLESS YOU KNOW WHAT YOU'RE DOING!
/////////////////////////////////////////////////////////////////////////////////////////////////////

//***Other Variables***
key owner;                          //tracks current owner
integer LISTEN_ID;                  //enables release of listens
integer INIT_RUN = 0;               //tracks how many times init() has run
integer MAX_INIT = 2;               //sets max number of times init() can run (default 2)
integer bug = 0;                    //triggers bugged state from a user-defined function
integer OBJSHOW;                    //tracks if object is shown (1) or hidden (0)
                                    //only used for default state, remains for debugging if needed
float SHOW_ALPHA = 1.0;             //default show alpha setting (1.0)
float HIDE_ALPHA = 0.0;             //default hide alpha setting (0.0)
integer FADEIN_STEPS;               //number of fade in increments
float FADEIN_TIME;                  //fade in time increment, NOT overall time
float FADEIN_ALPHA;                 //fade in alpha increment, NOT overall alpha
integer FADEOUT_STEPS;              //number of fade out increments
float FADEOUT_TIME;                 //fade out time increment, NOT overall time
float FADEOUT_ALPHA;                //fade out alpha increment, NOT overall alpha

// LEARNING LESSON NOTE:  I had to redo the trigger (event) in the default state to accommodate
// ownership change.  This entailed redoing the architecture of the whole state-based system.
// Initially I had the default state just proceeding to the correct state, with chat commands in
// each state triggering object alpha change directly.  Instead, now object alpha change occurs at
// state entry and chat commands subsequently trigger state change.  This enables a listen event in
// default state to trigger initial state change after ownership update.

// SECOND NOTE:  This kind of architecture is probably due to the nature of the script.  Most
// public scripts (e.g., chairs) respond to the user, not the owner per se.  In addition, I'm using
// chat commands as triggers instead of something firmer like a touch event.

//***USER-DEFINED FUNCTIONS***
checkgvar() {                       //checks global variables for compliance with bounds
    if(CHANNEL<=0) {
        llOwnerSay("***Bad value!  CHANNEL <= 0  (Error UD-CV01)***");
        bug=1;
    }
    integer CHECK = 0;
    if(HIDE_START == 0) CHECK = 1;
    else if(HIDE_START == 1) CHECK = 1;
    if(CHECK == 0) {
        llOwnerSay("***Bad value!  HIDE_START != 0 or 1  (Error UD-CV02)***");
        bug=1;
    }
    CHECK = 0;
    if(SHOWOBJ_ON == 0) CHECK = 1;
    else if(SHOWOBJ_ON == 1) CHECK = 1;
    if(CHECK == 0) {
        llOwnerSay("***Bad value!  SHOWOBJ_ON != 0 or 1  (Error UD-CV03)***");
        bug=1;
    }
    CHECK = 0;
    if(FADEIN_ON == 0) CHECK = 1;
    else if(FADEIN_ON == 1) CHECK = 1;
    if(CHECK == 0) {
        llOwnerSay("***Bad value!  FADEIN_ON != 0 or 1  (Error UD-CV04)***");
        bug=1;
    }
    CHECK = 0;
    if(HIDEOBJ_ON == 0) CHECK = 1;
    else if(HIDEOBJ_ON == 1) CHECK = 1;
    if(CHECK == 0) {
        llOwnerSay("***Bad value!  HIDEOBJ_ON != 0 or 1  (Error UD-CV05)***");
        bug=1;
    }
    CHECK = 0;
    if(FADEOUT_ON == 0) CHECK = 1;
    else if(FADEOUT_ON == 1) CHECK = 1;
    if(CHECK == 0) {
        llOwnerSay("***Bad value!  FADEOUT_ON != 0 or 1  (Error UD-CV06)***");
        bug=1;
    }
}

setcvar() {                         //checks & sets custom variables if either custom is in use
    if(SHOW_CALPHA>1.0) {
        llOwnerSay("***Bad value!  SHOW_CALPHA > 1.0  (Error UD-SV01)***");
        bug=1;
    }
    else if(SHOW_CALPHA<=0.0) {
        llOwnerSay("***Bad value!  SHOW_CALPHA <= 0.0  (Error UD-SV02)***");
        bug=1;
    }
    else if(HIDE_CALPHA<0.0) {
        llOwnerSay("***Bad value!  HIDE_CALPHA < 0.0  (Error UD-SV03)***");
        bug=1;
    }
    else if(HIDE_CALPHA>=1.0) {
        llOwnerSay("***Bad value!  HIDE_CALPHA >= 1.0  (Error UD-SV04)***");
        bug=1;
    }
    else if(SHOW_CALPHA<=HIDE_CALPHA) {
        llOwnerSay("***Bad value!  SHOW_CALPHA <= HIDE_CALPHA  (Error UD-SV05)***");
        bug=1;
    }
    if(FADEIN_ON == 1 && bug == 0) {
        if(FADEIN_SPD == 0) {
            if(FADEIN_CSTEPS<1) {
                llOwnerSay("***Bad value!  FADEIN_CSTEPS < 1  (Error UD-SV06)***");
                bug=1;
            }
            else if(FADEIN_CTIME<1.0) {
                llOwnerSay("***Bad value!  FADEIN_CTIME < 1.0  (Error UD-SV07)***");
                bug=1;
            }
            if(bug == 0) {
                SHOW_ALPHA = SHOW_CALPHA;
                HIDE_ALPHA = HIDE_CALPHA;
                FADEIN_STEPS = FADEIN_CSTEPS;
                FADEIN_ALPHA = (SHOW_CALPHA-HIDE_CALPHA) / (float)FADEIN_CSTEPS;
                FADEIN_TIME = FADEIN_CTIME / (float)FADEIN_CSTEPS;
            }
        }
        else if(FADEIN_SPD == 1) {  //10 steps over 5 seconds, assumes normal alphas for show/hide
            FADEIN_STEPS = 10;       // = given
            FADEIN_ALPHA = 0.1;     // = delta-alpha / steps = 1.0 / steps
            FADEIN_TIME = 0.5;      // = total-time / steps
        }
        else if(FADEIN_SPD == 2) {  //6 steps over 3 seconds, assumes normal alphas for show/hide
            FADEIN_STEPS = 6;
            FADEIN_ALPHA = 0.2;
            FADEIN_TIME = 0.5;
        }
        else if(FADEIN_SPD == 3) {  //5 steps over 1 second, assumes normal alphas for show/hide
            FADEIN_STEPS = 5;
            FADEIN_ALPHA = 0.2;
            FADEIN_TIME = 0.2;
        }
        else {
            llOwnerSay("***Bad value!  FADEIN_SPD != 0,1,2,3  (Error UD-SV08)***");
            bug=1;
        }
    }
    if(FADEOUT_ON == 1 && bug == 0) {
        if(FADEOUT_SPD == 0) {
            if(FADEOUT_CSTEPS<1) {
                llOwnerSay("***Bad value!  FADEOUT_CSTEPS < 1  (Error UD-SV9)***");
                bug=1;
            }
            else if(FADEOUT_CTIME<1.0) {
                llOwnerSay("***Bad value!  FADEOUT_CTIME < 1.0  (Error UD-SV10)***");
                bug=1;
            }
            if(bug == 0) {
                SHOW_ALPHA = SHOW_CALPHA;
                HIDE_ALPHA = HIDE_CALPHA;
                FADEOUT_STEPS = FADEOUT_CSTEPS;
                FADEOUT_ALPHA = (SHOW_CALPHA-HIDE_CALPHA) / (float)FADEOUT_CSTEPS;
                FADEOUT_TIME = FADEOUT_CTIME / (float)FADEOUT_CSTEPS;
            }
        }
        else if(FADEOUT_SPD == 1) {  //10 steps over 5 seconds, assumes normal alphas for show/hide
            FADEOUT_STEPS = 10;
            FADEOUT_ALPHA = 0.1;
            FADEOUT_TIME = 0.5;
        }
        else if(FADEOUT_SPD == 2) {  //6 steps over 3 seconds, assumes normal alphas for show/hide
            FADEOUT_STEPS = 6;
            FADEOUT_ALPHA = 0.2;
            FADEOUT_TIME = 0.5;
        }
        else if(FADEOUT_SPD == 3) {  //5 steps over 1 second, assumes normal alphas for show/hide
            FADEOUT_STEPS = 5;
            FADEOUT_ALPHA = 0.2;
            FADEOUT_TIME = 0.2;
        }
        else {
            llOwnerSay("***Bad value!  FADEOUT_SPD != 0,1,2,3  (Error UD-SV11)***");
            bug=1;
        }
    }
}

init() {                            //ensures proper ownership update on change
    if(INIT_RUN < MAX_INIT) {       //prevents this from running more than MAX_INIT times
        owner = llGetOwner();
        llListenRemove(LISTEN_ID);
        LISTEN_ID = llListen(CHANNEL,"",owner,"");
        ++INIT_RUN;
    }
}

//***START HERE: DEFAULT STATE RUNS ONCE ON OBJECT REZ OR SCRIPT RESET***
default {
    state_entry() {
        string temp = llStringTrim(commshow,STRING_TRIM);
        commshow = llToUpper(temp);                        //trim and capitalize commshow
        temp = llStringTrim(commhide,STRING_TRIM);
        commhide = llToUpper(temp);                        //trim and capitalize commhide
        temp = llStringTrim(commreset,STRING_TRIM);
        commreset = llToUpper(temp);                       //trim and capitalize commreset
        checkgvar();                                       //check g variables for compliance
        if(bug == 1) {                                     //trigger bug if checkgvar() fails
            llListenRemove(LISTEN_ID);
            state bugged;
        }
        if(FADEIN_ON == 1 || FADEOUT_ON == 1) setcvar();   //check & set c variables if any fading
        if(bug == 1) {                                     //trigger bug if check in setcvar() fails
            llListenRemove(LISTEN_ID);
            state bugged;
        }
        if(HIDE_START == 1) {                              //set correct start based on HIDE_START
            llSetLinkAlpha(LINK_SET, HIDE_ALPHA, ALL_SIDES);
            OBJSHOW = 0;
        }
        else {
            llSetLinkAlpha(LINK_SET, SHOW_ALPHA, ALL_SIDES);
            OBJSHOW = 1;
        }
        init();
    }
    on_rez(integer start_param) {
        init();
    }
    changed(integer change) {
        if(change & CHANGED_OWNER) {
            init();
        }
    }
    listen (integer channel, string name, key id, string command) {
        string temp = llStringTrim(command,STRING_TRIM);
        command = llToUpper(temp);
        if(command == commshow && OBJSHOW == 0) {
            llListenRemove(LISTEN_ID);
            state showme;
        }
        else if(command == commhide && OBJSHOW == 1) {
            llListenRemove(LISTEN_ID);
            state hideme;
        }
        else if(command == commreset) {
            llListenRemove(LISTEN_ID);
            llResetScript();
        }
    }
}

//***WHEN OBJECT IS TO BE SHOWN***
state showme {
    state_entry() {
        if(FADEIN_ON == 0) {
            llSetLinkAlpha(LINK_SET, SHOW_ALPHA, ALL_SIDES);
            OBJSHOW = 1;
        }
        else {
            integer i;
            float ALPHA_TEMP;
            integer ONCERUN = 0;
            for(i=1;i<=FADEIN_STEPS;++i) {
                ALPHA_TEMP = (float)i * FADEIN_ALPHA;
                if(ALPHA_TEMP<=1.0 && ALPHA_TEMP>0.0) {
                    if(i==1) ONCERUN = 1;
                    llSetLinkAlpha(LINK_SET, ALPHA_TEMP, ALL_SIDES);
                    llSleep(FADEIN_TIME);
                }
            }
            if(ALPHA_TEMP <= 0.0) llSetLinkAlpha(LINK_SET, SHOW_ALPHA, ALL_SIDES);
            else if(ALPHA_TEMP > 1.0) llSetLinkAlpha(LINK_SET, SHOW_ALPHA, ALL_SIDES);
            if(ALPHA_TEMP != SHOW_ALPHA) llSetLinkAlpha(LINK_SET, SHOW_ALPHA, ALL_SIDES);
            if(ONCERUN == 0) llSetLinkAlpha(LINK_SET, SHOW_ALPHA, ALL_SIDES);
            OBJSHOW = 1;
        }
        LISTEN_ID = llListen(CHANNEL, "", owner, "");
    }
    listen (integer channel, string name, key id, string command) {
        string temp = llStringTrim(command,STRING_TRIM);
        command = llToUpper(temp);
        if(command == commhide && HIDEOBJ_ON == 1) {
            llListenRemove(LISTEN_ID);
            state hideme;
        }
        else if(command == commreset) {
            llListenRemove(LISTEN_ID);
            llResetScript();
        }
    }
}

//***WHEN OBJECT IS TO BE HIDDEN***
state hideme {
    state_entry() {
        if(FADEOUT_ON == 0) {
            llSetLinkAlpha(LINK_SET, HIDE_ALPHA, ALL_SIDES);
            OBJSHOW = 0;
        }
        else {
            integer i;
            float ALPHA_TEMP;
            integer ONCERUN = 0;
            for(i=FADEOUT_STEPS;i>0;--i) {
                ALPHA_TEMP = ((float)i - 1.0) * FADEOUT_ALPHA;
                if(ALPHA_TEMP>=0.0 && ALPHA_TEMP<1.0) {
                    if(i==FADEOUT_STEPS) ONCERUN = 1;
                    llSetLinkAlpha(LINK_SET, ALPHA_TEMP, ALL_SIDES);
                    llSleep(FADEOUT_TIME);
                }
            }
            if(ALPHA_TEMP < 0.0) llSetLinkAlpha(LINK_SET, HIDE_ALPHA, ALL_SIDES);
            else if(ALPHA_TEMP >= 1.0) llSetLinkAlpha(LINK_SET, HIDE_ALPHA, ALL_SIDES);
            if(ALPHA_TEMP != HIDE_ALPHA) llSetLinkAlpha(LINK_SET, HIDE_ALPHA, ALL_SIDES);
            if(ONCERUN == 0) llSetLinkAlpha(LINK_SET, HIDE_ALPHA, ALL_SIDES);
            OBJSHOW = 0;
        }
        LISTEN_ID = llListen(CHANNEL, "", owner, "");
    }
    listen (integer channel, string name, key id, string command) {
        string temp = llStringTrim(command,STRING_TRIM);
        command = llToUpper(temp);
        if(command == commshow && SHOWOBJ_ON == 1) {
            llListenRemove(LISTEN_ID);
            state showme;
        }
        else if(command == commreset) {
            llListenRemove(LISTEN_ID);
            llResetScript();
        }
    }
}

//***BAD VARIABLE VALUE SOMEWHERE***
state bugged {
    state_entry() {
        llOwnerSay("***Script operation terminated!***");
    }
}

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...