Butterflies, part 2

Yesterday we talked about a script to add to some cheap copy mod butterflies available on the marketplace to prepare them for use in a rezzer.  Today, we’ll look at the rezzer script and how to put it all together.

Let’s jump in and look at the rezzer script right away.  All we are going to have to do is place this, an optional notecard, and our modified butterflies in a prim, and we’ll be ready to go!  Here’s the script (don’t panic, it’s a little larger than yesterdays!):

 

integer g_rezzed;
integer g_chan = -88503;
integer g_nc_line;
integer g_rez_count;
integer g_pos_count;
integer g_obj_count;
key g_nc_id;
list g_positions;
list g_objects;
string g_nc_name = "config";

default {
    
    on_rez (integer n) {
        llResetScript ();
    }
    
    changed (integer c) {
        if (c & CHANGED_INVENTORY || c & CHANGED_REGION_START) {
            llResetScript ();
        }
    }
    
    state_entry () {
        llRegionSay (g_chan, "SWAT!");
        integer i;
        g_objects = [];
        g_positions = [];
        g_pos_count = 0;
        string name;
        integer n = llGetInventoryNumber (INVENTORY_OBJECT);
        for (i = 0; i < n; i++) { 
            name = llGetInventoryName (INVENTORY_OBJECT, i);
            if (llGetSubString (name, 0, -2) == "butterflys") {
                g_objects += name;
            }
        }
        g_obj_count = llGetListLength (g_objects);
        if (g_obj_count == 0) {
            llOwnerSay ("There are no butterflys objects in the inventory!");
            return;
        }
        g_rezzed = FALSE;
        g_nc_line = 0;
        if (llGetInventoryType (g_nc_name) == INVENTORY_NOTECARD) {
            g_nc_id = llGetNotecardLine (g_nc_name, g_nc_line);
        } else {
            llSetTimerEvent (30.0);
        }
    }

    dataserver (key id, string data) {
        if (id == g_nc_id) {
            if (data != EOF) {
                if (llGetSubString (data, 0, 0) != "#") {
                    g_positions += (vector)data;
                    llRegionSay (g_chan + g_nc_line, "SWAT!");
                }
                g_nc_id = llGetNotecardLine (g_nc_name, ++g_nc_line);
            } else {
                g_pos_count = llGetListLength (g_positions);
                llSetTimerEvent (30.0);
            }
        }
    }

    timer () {
        vector sun = llGetSunDirection ();
        if (sun.z > 0) {
            if (g_rezzed == FALSE) {
                integer i;
                for (i = 0; i < g_pos_count + 1; i++) {
                    llRezObject (llList2String (g_objects, (integer)llFrand (g_obj_count)),
                                 llGetPos () + <0.0, 0.0, 1.5>,
                                 ZERO_VECTOR,
                                 ZERO_ROTATION,
                                 g_chan + i);
                    g_rez_count++;
                }
                g_rezzed = TRUE;
            }
        } else {
            if (g_rezzed == TRUE) {
                integer i;
                for (i = 0; i < g_pos_count + 1; i++) {
                    llRegionSay (g_chan + i, "SWAT!");
                }
                g_rezzed = FALSE;
            }
        }
    }

    object_rez (key id) {
        if (--g_rez_count > 0) {
            llSay (g_chan + g_rez_count - 1,
                   (string)llList2Vector (g_positions, g_rez_count - 1));
        }
    }
    
    touch_start (integer n) {
        if (g_rezzed == TRUE) {
            integer i;
            for (i = 0; i < g_pos_count + 1; i++) {
                llRegionSay (g_chan + i, "SWAT!");
            }
            g_rezzed = FALSE;
        }
    }
}

 

OMG you might be saying 🙂 Let’s take it slow, and go through this. I’ll describe each event handler, so hopefully you can grasp what’s going on.

  • on_rez – we are just restarting the script.
  • changed – we restart the script on a region restart so as to make sure we either rez or derez the butterflies.  We also restart if the inventory changes, which makes it easy to add lines to the notecard for additional butterflies .
  • state_entry – we initialize some variables, find the names of the butterfly objects in our inventory (remember, I said yesterday to name the butterfly objects “butterflys1”, “butterflys2”, and “butterflys3”?).  Then we start reading our notecard, which will transfer control to…
  • dataserver – which gets each line in our notecard, and stores the data in a variable called g_positions, and once we hit the end of the notecard, we start a 30 second timer.  We also derez any existing butterfly objects.
  • timer – here’s where all the work gets done.  Every 30 seconds, we check if the sun is up (indicated by the Z value of the sun’s position).  If the sun is up, and we haven’t rezzed any butterflies yet, rez a randomly selected butterfly object from our inventory 1.5 metres above the rezzer for each of the positions in our notecard.  If the sun is not up, say “SWAT!” to each of our rezzed butterflies on the channel they are listening on to delete them.  Note the last parameter of the llRezObject call.  It tells each butterfly object what channel to listen on (the parameter in the on_rez event of yesterday’s script).  Also note that the rez loop rezzes one additional butterfly object and leaves it above the rezzer.   This makes it easy if you just want one butterfly set.
  • object_rez – here we tell each newly rezzed butterfly object the position it should move to.
  • touch_start – just in case you need to reset everything, you can touch the rezzer to delete any existing butterflies.

We need an optional notecard in the rezzer’s contents called “config”.  It consists of lines containing positions in region co-ordinates where you want additional butterflies to be.  You can also comment out a line by putting a hash in the first column.  So you might have something like this:

# butterflies for woods
<104.3, 10.5, 26.0>
# for skybox
<218.5, 132.5, 2026.0>

After all that we better have a picture 🙂

Here’s a screen shot of the rezzer with the config notecard, the above script, and the butterfly objects in its contents:

Here I’ve made the rezzer white so you can see it, but you should set it to 100% transparent, and phantom too.  You also must call the rezzer “Butterfly rezzer”, because that’s what our script from yesterday is expecting.

And that’s it!  If you’ve followed along with the instructions, 30 seconds after you drop the script in the rezzer, your butterflies should rez!  Assuming the sun is up 🙂  Take the rezzer into your inventory and position where you want one set of butterflies to be.  Add lines to the config notecard for additional ones!  Have fun!