Programs that build things
RezzerThe command llRezObject is one of the best in LSL!
Create a cube, call it "myCube", an put it into your Inventory. (You can put a texture on it if you want, but any old cube will do. It does not need a script or anything.)
Then create another cube, which you could call "Newbie". Open up Newbie's contents in the editor, and drag a copy of "myCube" into the contents from your Inventory. Now create a new script in Newbie, and add line 11 like this:
default { state_entry() { llSay(0, "Hello, Avatar!"); } touch_start(integer total_number) { llSay(0, "Touched."); llRezObject("myCube", llGetPos()+<0,0,1>, ZERO_VECTOR, ZERO_ROTATION, 33); } } See what happens when you touch Newbie: a copy of myCube gets rezzed into a spot 1m above Newbie! Try deleting the copy and touching Newbie again!
Now your scripts can create things!
I assume that you finally succeeded in getting those sunsetSpheres into your Inventory! Now we can create as many of those as we like, and since they politely destroy themselves, we do not clutter up the landscape! Put a copy of a sunsetSphere into the contents of a new object, together with the 3 tones we used earlier, tone1, tone2, tone3. Finally, give the object this script:
default { state_entry() { llSay(0, "Hello, Avatar! I am a rezzer"); } touch_start(integer total_number) { llSay(0, "Touched."); llRezObject("sunsetSphere", llGetPos()+<0,0,1>, ZERO_VECTOR, ZERO_ROTATION, 42); llTriggerSound("tone1",1.0); llSleep(0.2); llRezObject("sunsetSphere", llGetPos()+<0,0,3>, ZERO_VECTOR, ZERO_ROTATION, 42); llTriggerSound("tone2",1.0); llSleep(0.2); llRezObject("sunsetSphere", llGetPos()+<0,0,2>, ZERO_VECTOR, ZERO_ROTATION, 42); llTriggerSound("tone3",1.0); llSleep(0.2); llRezObject("sunsetSphere", llGetPos()+<0,0,5>, ZERO_VECTOR, ZERO_ROTATION, 42); llTriggerSound("tone1",1.0); llSleep(0.2); llRezObject("sunsetSphere", llGetPos()+<0,0,4>, ZERO_VECTOR, ZERO_ROTATION, 42); llTriggerSound("tone2",1.0); llSleep(0.2); } } What will this object do, each time you touch it? Try it and see! This is one of my favorite programs! (If it does not sound evenly spaced, then your computer is probably experiencing some "lag". You could try adjusting the sleep times.)
By now, you might have ideas about things you would like to have other objects build for you! With some more practice, you can get good at writing programs to build quite a few things!
We have ignored particles!
integer i = 0; default { state_entry() { llSay(0, "Hello, Avatar!"); } touch_start(integer total_number) { if (i==0) { llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_WIND_MASK | PSYS_PART_EMISSIVE_MASK, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE, PSYS_PART_START_COLOR, <1,0,0>]); i=1; } else { llParticleSystem([]); i=0;} } } This llParticleSystem command is the example from the lsl wiki. Try it out!
Notice how we use == in the test, and = to change the value of i.
And notice that particle systems don't stop by themselves! You have to turn them off by setting their properties back to nothing [].
There is a useful page just about particles here
This program creates a "building" that is "minimalist" but kind of cool. In Second Life, that open look is nice, so you can fly off from anywhere in the building!. (You might have seen me bring out this building before...but you might not have known that a program can build this!) And so far I only furnished the top floor, with a nice big vase. But you'll see that the building could be MUCH fancier with a little work..
(This picture makes the tensile strength of the ramps and floors look very high! But really, these pieces are not marked "physical" and so we can suspend them wherever we want. Each piece is separately positioned and then linked with a bond of infinite strength. This makes getting the approval from the structural engineers much easier than it is in the real world!)
This is the most complicated script in this whole blog. But if you want to understand it, you can. All the parts are quite simple. You might want to try this script out before studying how it works.
In this program, only one object -- the one with this script -- does all the rezzing, so we position that object, the builder, near the middle of the building. (It is easy for things to get out of range!) This builder uses a floor and a ramp and a vase, which you can get from me or Tiplife in the box for this blog. These things are called floor2, ramp2, and Vase2, and they must be in the Contents of the builder, as usual.
There are 2 new things in this script. 1. The "linking" of multiple objects into one. It would be good to practice linking things together by hand before tackling this script. And 2. specifying rotations other than zero. We do this by saying what the Euler angles are and then converting to rotations (quaternions). Make Hector or Tiplife explain everything to you!
integer createdObjectCounter; integer linkedObjectCounter; vector builderOffset = <0.0,0.0,9.4>; // we raise the builder to keep it nearer the center of the structure // even floors and odd floors are over each other, so we put their positions here vector oddFloor = <0.00,7.78,3.38>; // floor 1 is first odd floor vector oddRamp = <-2.00,-0.30,1.5>; vector floorEuler = <0.00,90.0,180.0>; vector oddRampEuler = <300.0,0.0,180.0>; vector upTwo = <0.00,0.00,7.45>; vector evenFloor = <0.00,-8.5,7.18>; vector evenRamp = <0.80,-0.20,5.20>; vector evenRampEuler = <60.0,0.0,0.0>; default { state_entry() { llOwnerSay("Hello, Avatar!"); } touch_start(integer total_number) { llSetPos(llGetPos() + builderOffset); // move builder upwards, closer to center of construction if( createdObjectCounter <= 0 ) // nothing has yet been linked, { // get permission to link things llRequestPermissions( llGetOwner(), PERMISSION_CHANGE_LINKS ); } } run_time_permissions(integer permissions_granted) { // even floors and odd floors are the same except for the z dimension! llOwnerSay("Got the go-ahead..."); // floor 1 -- we create first floor and a ramp up to it, ready to be linked llRezObject("floor2", llGetPos() + (oddFloor - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * floorEuler), 42); createdObjectCounter = createdObjectCounter + 1; llRezObject("ramp2", llGetPos()+ (oddRamp - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * oddRampEuler), 42); createdObjectCounter = createdObjectCounter + 1; // floor 2 -- one more level llRezObject("floor2", llGetPos() + (evenFloor - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * floorEuler), 42); createdObjectCounter = createdObjectCounter + 1; llRezObject("ramp2", llGetPos()+ (evenRamp - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * evenRampEuler), 42); createdObjectCounter = createdObjectCounter + 1; // floor 3 llRezObject("floor2", llGetPos() + ((oddFloor + upTwo) - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * floorEuler), 42); createdObjectCounter = createdObjectCounter + 1; llRezObject("ramp2", llGetPos()+ ((oddRamp + upTwo) - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * oddRampEuler), 42); createdObjectCounter = createdObjectCounter + 1; // floor 4 llRezObject("floor2", llGetPos() + ((evenFloor + upTwo) - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * floorEuler), 42); createdObjectCounter = createdObjectCounter + 1; llRezObject("ramp2", llGetPos()+ ((evenRamp + upTwo) - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * evenRampEuler), 42); createdObjectCounter = createdObjectCounter + 1; // furnishings llRezObject("Vase2", llGetPos() + (((evenFloor + upTwo) + <0.0,0.0,0.7>) - builderOffset), ZERO_VECTOR, llEuler2Rot(DEG_TO_RAD * <0.0,90.0,0.0>), 42); } object_rez( key child_id ) { // this section is mainly just to show that we can control things here llOwnerSay( "rez produced object with key " + (string)child_id ); // link as parent to the just created child llCreateLink( child_id, TRUE ); linkedObjectCounter++; if( linkedObjectCounter >= 2 ) { // Change linked objects grey -- (you could do something fancier!) llSetLinkColor( LINK_ALL_CHILDREN, < 0.3, 0.3, 0.3 >, ALL_SIDES ); // Change transparency of linked objects llSetLinkAlpha( 2, .5, ALL_SIDES ); } } } You can make the builder box transparent, or wood, or you can make it into a beautiful chandelier! The code in the last block links all the objects together so that they move as one unit, changes their colors and transparency changed all at once, etc. Here, you could put a zebra stripe texture on everything if you wanted. (This last block, the linking code, is based on an idea from here.)
Do you think Hector needs to go back to Architecture School?
There is a blog devoted to Second Life architecture, where you can see pictures of lots of much fancier designs (including some more conventional ones -- you might not be ready for Hector's radical designs yet) here. There are even whole architecture classes given in Second Life. The slogan of the Second Life class "Production of Architecture" at the Royal Institute of Technology, Stockholm: On our way to innovation we passed something beautiful.