Pipe Maker

Expired

// PipeMaker by Lex Neva
//
// Pipemaker helps you easily create continuous lengths of pipe using cylinders and torus segments. The simple dialog-driven
// interface always lines pieces up perfectly to give you one long continuous pipe. It's useful for creating industrial
// complicated pipe messes, weird curlicues, and, of course, for writing your name in prims in the air.
//
// This script is released under the GNU Public License (http://www.gnu.org for a copy). In short, this means you may copy,
// redistribute, and modify this script to your heart's content, so long as my name stays in it and your new version is also
// freely redistributable. For more details, read the full license. If you really must provide me with some kind of compensation
// for my work, feel free to heap praises upon me in the forums, rate me, and/or send me lindens. You can also check out my
// store in Eldora.
//
// Okay, now that's out of the way. Here's how to use this thing.
//
// If you've managed to pick up a copy of this script in the wild, you'll have to build the object. Fortunately, that's easy.
//
// 1. Build a default cylinder, name it PipeMaker (the name's important)
// 2. Place this script in the PipeMaker cylinder.
// 3. Take a copy. (leave one rezzed)
// 4. Find the copy in your inventory, and place it in the rezzed one.
// 5. Take the whole mess into your inventory.
// 6. Rez a copy and get started!
//
// The above process is necessary because the pipemaker uses a safe form of self-replication.
//
// Now, how to actually make pipes.
//
// You should be able to just rez the PipeMaker object and go to it. A dialog will pop up, and a new pipe piece will stick itself
// onto the end of the first one. This new piece (the red one) is the one you're currently working on. Poke a few buttons.
// Commands like "length+" will make the length of a straight piece longer. The more pluses, the longer it'll get. Minuses will
// shrink it instead.
//
// Click the "curve" button if you want to turn a corner instead. The radius commands will change how sharp the curve is: bigger
// radius means a more gradual curve. The arc commands will determine how much of a circle the curved piece uses. 90 means to
// turn a right angle, 180 means to do a "U" bend, etc. 360 probably won't be useful, but the option IS there. Tilt will
// make the curved piece rotate up or down. Just play with it, you'll get it.
//
// There are only so many buttons allowable in a script dialog, so I wasn't able to include all of the commands I wanted to. You
// can still do things like "radius+++" if the radius+ button isn't going fast enough: just type /1 radius+++. You can use up to
// three pluses or minuses.
//
// When you're done, just delete the extra red piece. I didn't have enough room for a "finish" button.
//
// If you want to have a hollow pipe, rez the first PipeMaker, and change its hollow value. Tweak the length so that the red
// pipe updates. From then on, the hollow will carry through. You could, if you want, change the hollow at any time, and
// the setting will carry on to pieces after that one. If you want to change the thickness of the pipe, just change the
// X and Y size of the starting cylinder. I recommend that the X and Y settings should be the same. I was too lazy to make
// it work with oval pipes. You can change the size any time, but I don't recommend messing with curved pieces, because getting
// everything to match up nicely is difficult.
//
// The rest is for advanced users. You can skip this stuff.
//
// Why isn't there finer control for arc and tilt? Why does radius change in such weird increments?
//
// The simple answer is that the object properties this script uses, such as hole size and cut, only allow two decimal places of
// precision. If I let you use any arc value, SL will "round" to the nearest 18 or so degrees, and that'll mean the next pipe
// doesn't join on perfectly. Radius is even more complicated. You can set the radius of a torus to a fairly fine degree of
// precision, but the real limiting factor is the hole size. If the hole size that would be needed for a certain radius
// of curve doesn't line up on an even 0.01, the pipe's cross-section won't match up. When you use the radius+ and radius-
// buttons, I actually decrement and increment the hole size, and figure out the torus's radius from that, which guarantees that
// everything lines up beautifully. Incidentally, I also change the tilt value in increments of 15 degrees, because that way
// the vertices of the cylinders and tori always line up nicely.
//
// That said, you can override these limits manually if you really want to. I figure if you want to do this, you probably have
// a good reason. Just utter these commands on channel 1 (by prefixing them with "/1"):
//
// radius 2.5
// tilt 35.0
// arc 90.0
// length 5.0
// radius+++
// (any other command on the buttons)
// reset (use only if the red prim fails to rez or is accidentally deleted)
//
// Just be careful, especially with radius. If you don't watch it, you can find that things aren't lining up nicely... it's just
// due to the limits of primitive properties. The dialog optiosn should give you a fair degree of freedom.
//
 
float torus_radius;
float torus_rot;
float torus_arc;
 
float cylinder_length;
 
integer type;
integer channel;
 
integer listenHandle;
 
vector offsetRot(vector initial_position, vector center_position, rotation rot_amount)
{
 
vector offset = initial_position - center_position;
 
vector final_position;
 
//The following line calculates the new coordinates based on
//the rotation & offset
final_position = offset * rot_amount;
 
//Since the rotation is calculated in terms of our offset, we need to add
//our original center_position back in - to get the final coordinates.
final_position += center_position;
 
return final_position;
}
 
makeTorus() {
//llSay(0,"Making torus part with radius " + (string)torus_radius + " rotation " + (string)torus_rot + " arc " + (string)torus_arc);
 
vector myScale = llGetScale();
rotation torus_rotation;
vector torus_position;
vector torus_scale;
vector torus_cut;
vector torus_hole_size;
list params = llGetPrimitiveParams([PRIM_TYPE]);
float hollow = llList2Float(params,3);
 
if (llList2Integer(params,0) == PRIM_TYPE_CYLINDER) {
 
torus_rotation = llGetRot();
torus_position = llGetPos() + llRot2Up(torus_rotation) * myScale.z * 0.5 - llRot2Left(torus_rotation) * (torus_radius - myScale.x/2.0);
 
vector face_center = llGetPos() + llRot2Up(torus_rotation) * myScale.z * 0.5;
rotation rot = llAxisAngle2Rot(llRot2Up(torus_rotation), DEG_TO_RAD * torus_rot);
 
torus_position = offsetRot(torus_position, face_center, rot);
torus_rotation = torus_rotation * rot;
torus_scale = ;
torus_hole_size = <1 .0,myScale.y/(2*torus_radius),0.0>;
} else {
 
vector cut = llList2Vector(params,2);
vector hole_size = llList2Vector(params,5);
float d = hole_size.y * myScale.y;
 
torus_rotation = llGetRot();
torus_position = llGetPos();
 
torus_rotation *= llAxisAngle2Rot(llRot2Fwd(torus_rotation),cut.y*TWO_PI);
torus_position += llRot2Left(torus_rotation) * (myScale.z/2.0 - torus_radius);
 
vector face_center = torus_position + llRot2Left(torus_rotation) * (torus_radius - d/2.0);
rotation rot = llAxisAngle2Rot(llRot2Up(torus_rotation), DEG_TO_RAD * torus_rot);
 
torus_position = offsetRot(torus_position, face_center, rot);
torus_rotation = torus_rotation * rot;
 
torus_scale = ;
torus_hole_size = <1 .0,d/(2*torus_radius),0.0>;
}
 
torus_cut = <0.0, torus_arc/360.0, 0.0>;
 
llSay(channel,"TORUS," + (string)torus_position + "," + (string)torus_rotation + "," + (string)torus_scale + "," + (string)torus_cut + "," + (string)hollow + "," + (string)torus_hole_size);
}
 
makeCylinder() {
//llSay(0,"Making cylinder with length " + (string)cylinder_length);
 
vector myScale = llGetScale();
rotation cylinder_rotation;
vector cylinder_position;
vector cylinder_scale;
float d;
list params = llGetPrimitiveParams([PRIM_TYPE]);
float hollow = llList2Float(params,3);
 
if (llList2Integer(params,0) == PRIM_TYPE_TORUS) {
 
vector cut = llList2Vector(params,2);
vector hole_size = llList2Vector(params,5);
d = hole_size.y * myScale.y;
 
cylinder_rotation = llGetRot();
rotation rot = llAxisAngle2Rot(llRot2Fwd(cylinder_rotation),cut.y *TWO_PI);
 
cylinder_rotation *= rot;
 
cylinder_position = llRot2Left(llGetRot()) * ((myScale.y - d)/2.0);
cylinder_position *= rot;
cylinder_position += llGetPos();
cylinder_position += llRot2Up(cylinder_rotation) * (cylinder_length/2.0);
} else {
d = myScale.y;
cylinder_position = llGetPos();
cylinder_rotation = llGetRot();
cylinder_position += llRot2Up(cylinder_rotation) * ((myScale.z + cylinder_length)/2.0);
}
 
cylinder_scale = ;
 
llSay(channel,"CYLINDER," + (string)cylinder_position + "," + (string)cylinder_rotation + "," + (string)cylinder_scale + "," + (string)hollow);
}
 
update() {
if (type == PRIM_TYPE_CYLINDER)
makeCylinder();
else
makeTorus();
}
 
rezNext() {
channel = 10000 + llFloor(llFrand(1000000));
 
//llOwnerSay("Channel = " + (string)channel);
 
llRezObject("PipeMaker",llGetPos(), ZERO_VECTOR, ZERO_ROTATION, channel);
llSleep(1.0);
}
 
sendDialog() {
 
if (type == PRIM_TYPE_CYLINDER) {
llDialog(llGetOwner(),"Straight piece\n\nlength = " + (string)cylinder_length + " meters",["length+","length++","length+++","length-","length--","length---","curve","next"],1);
} else {
llDialog(llGetOwner(),"Curve piece\n\nradius = " + (string)torus_radius + " meters\narc = " + (string)torus_arc + " degrees\ntilt = " + (string)torus_rot + " degrees",["tilt+","tilt++","next","tilt-","tilt--","straight","radius+","arc+","arc++","radius-","arc-","arc--"],1);
}
}
 
float getDiameter() {
vector scale = llGetScale();
return scale.x;
}
 
init() {
float d = getDiameter();
 
if (d > 2.5) {
torus_radius = d;
} else {
torus_radius = d*2.0;
}
 
torus_rot = 0.0;
torus_arc = 90.0;
cylinder_length = 1.0;
type=PRIM_TYPE_CYLINDER;
}
 
default
{
on_rez(integer param) {
if (param) {
llListen(param,"","","");
llSetColor(<1 .0,0.0,0.0>,ALL_SIDES);
} else {
llSetColor(<1 ,1,1>,ALL_SIDES);
state configure;
}
}
 
listen(integer c, string name, key id, string message) {
list params = llCSV2List(message);
list primParams;
if (llList2String(params,0) == "TORUS") {
primParams = [PRIM_POSITION, (vector)llList2String(params,1),
PRIM_ROTATION, (rotation)llList2String(params,2),
PRIM_SIZE, (vector)llList2String(params,3),
PRIM_TYPE,
PRIM_TYPE_TORUS, // type
PRIM_HOLE_DEFAULT, // hole type
(vector)llList2String(params,4), // cut
(float)llList2String(params,5), // hollow
<0.0,0.0,0.0>, // twist
(vector)llList2String(params,6), // hole size
<0.0,0.0,0.0>, // top shear
<0.0,1.0,0.0>, // advanced cut
<0.0,0.0,0.0>, // taper
1.0, // revolutions
0.0, // radius offset
0.0 // skew
];
} else if (llList2String(params,0) == "CYLINDER") {
primParams = [PRIM_POSITION, (vector)llList2String(params,1),
PRIM_ROTATION, (rotation)llList2String(params,2),
PRIM_SIZE, (vector)llList2String(params,3),
PRIM_TYPE,
PRIM_TYPE_CYLINDER, // type
PRIM_HOLE_DEFAULT, // hole type
<0.0,1.0,0.0>, // cut
(float)llList2String(params,4), // hollow
<0.0,0.0,0.0>, // twist
<1 .0, 1.0, 0.0>, // top size
<0.0,0.0,0.0> // top shear
];
} else if (llList2String(params,0) == "DONE") {
llSetColor(<1 .0,1.0,1.0>,ALL_SIDES);
state configure;
}
 
llSetPrimitiveParams(primParams);
 
}
}
 
state configure {
state_entry() {
listenHandle = llListen(1,"",llGetOwner(),"");
 
init();
 
sendDialog();
rezNext();
update();
}
 
on_rez(integer param) {
llListenRemove(listenHandle);
listenHandle = llListen(1,"",llGetOwner(),"");
llSetColor(<1 ,1,1>,ALL_SIDES);
 
init();
 
sendDialog();
rezNext();
update();
}
 
changed(integer change) {
if (change & CHANGED_SHAPE) {
// hollow
update();
} else if (change & CHANGED_SCALE) {
float d = getDiameter();
 
// must make sure the hole size will be nice and prim size will be under 10.0
if (d > 2.5)
torus_radius = d;
else
torus_radius = d * 2.0;
update();
}
}
 
moving_end() {
update();
}
 
listen(integer c, string name, key id, string message) {
list parts = llParseString2List(message,[" "],[]);
string command = llList2String(parts,0);
 
// start with chat-only commands, don't resend dialog (it gets spammy)
if (command == "radius") {
torus_radius = (float)llList2String(parts,1);
} else if (command == "rot" || command == "tilt") {
torus_rot = (float)llList2String(parts,1);
} else if (command == "arc") {
torus_arc = (float)llList2String(parts,1);
} else if (command == "length") {
cylinder_length = (float)llList2String(parts,1);
} else if (command == "done" || command == "next") {
llSay(channel,"DONE");
 
// now commit suicide
llRemoveInventory(llGetScriptName());
state default; // and just in case, stop doing anything until the script's removed.
} else {
// dialog-driven commands follow, this big else block is so I can send a dialog only for dialog commands
 
if (command == "curve") {
type = PRIM_TYPE_TORUS;
} else if (command == "straight") {
type = PRIM_TYPE_CYLINDER;
} else if (llGetSubString(command,0,5) == "length") {
integer strength = llStringLength(command) - 6;
float change = llList2Float([0.1,0.5,1.0],strength - 1);
 
if (llGetSubString(command,6,6) == "-")
change *= -1;
 
cylinder_length += change;
 
if (cylinder_length <0.01)
cylinder_length = 0.01;
if (cylinder_length > 10.0)
cylinder_length = 10.0;
} else if (llGetSubString(command,0,5) == "radius") {
integer strength = llStringLength(command) - 6;
float change = llList2Float([0.01,0.05,0.1], strength - 1);
 
if (llGetSubString(command,6,6) == "+")
change *= -1;
 
float d = getDiameter();
float hole_size = d/(torus_radius * 2.0);
 
hole_size += change;
 
if (hole_size <0.05) {
//llOwnerSay("clamped to 0.05");
hole_size = 0.05;
} if (hole_size > 0.5) {
//llOwnerSay("clamped to 0.5");
hole_size = 0.5;
}
 
float new_radius = d/(hole_size * 2.0);
 
if (new_radius <= 5.0) {
torus_radius = new_radius;
}
} else if (llGetSubString(command,0,2) == "arc") {
integer strength = llStringLength(command) - 3;
float change = llList2Float([0.05,0.1,0.2], strength - 1);
 
if (llGetSubString(command,3,3) == "-")
change *= -1;
 
float cut = torus_arc / 360.0;
 
cut += change;
 
if (cut > 1.0)
cut = 1.0;
if (cut <0.05)
cut = 0.05;
 
torus_arc = cut * 360.0;
} else if (llGetSubString(command,0,3) == "tilt") {
integer strength = llStringLength(command) - 4;
float change = llList2Float([15.0,45.0,90.0], strength - 1);
 
if (llGetSubString(command,4,4) == "-")
change *= -1;
 
torus_rot += change; // boundaries wrap
} else if (command == "reset") {
init();
rezNext();
} else {
return; // invalid command
}
 
sendDialog();
}
 
// in any case, if we get here, it's time to update the next segment's properties
update();
}
 
touch_start(integer num) {
sendDialog();
}
 
object_rez(key id) {
llGiveInventory(id, "PipeMaker");
}
}

 

Prim Calculator

Expired

 
// Tells you the number of prims that can be used on a given size of lot.
// Tells you the amount of land you must own to support a certain number of prims.
// Example: "/land 512" or "/prims 100"
 
default
{
    state_entry()
    {
        llListen(0,"",llGetOwner(),"");
    }
 
    listen(integer channel, string name, key id, string m)
    {
        integer command_divide = llSubStringIndex(m," "); // establish that space (" ") divides words.
 
        string gCommand = llToLower(llGetSubString(m, 0, command_divide - 1)); // grab the first word of the the input string.
        string gSubCommand = llToLower(llGetSubString(m, command_divide + 1, 40)); // grab the rest of the input string.
 
        // Calculate Prims
        if (gCommand == "/land")
        {
            float land = (float)gSubCommand;
            float primsF = land / 65536 * 15000;
            integer primsI = (integer)primsF; // converts the float to an integer for easier reading. Note that land must be purchased in parcels of 16 square metres.
 
            llSay(0,"You can use up to " + (string)primsI + " prims.");
        }
 
        // Calculate Land
        if (gCommand == "/prims")
        {
            integer prims = (integer)gSubCommand;
            integer land = prims * 65536 / 15000;
            llSay(0,"You need " + (string)land + " square metres of land to support " + (string)prims + " prims.");
        }
    }
}

 

Prim Server (Giver)

Expired

The Server Giver needs 2 objects, with each a script inside:
1 with the Server Prim Script
2 with the Server Child Prim Script

The object with the Server Prim Script handles the requests coming from the Child Prim.
You can make as many copies of the Child Prim. They will all make their requests to the same Server Prim.

QUICK SETUP
—————–

1. Create an object and name it “Child”. Open the Content tab, click New Script and replace the Hello Avatar script with the SERVER Child Prim Script
2. Create an object and name it “Server”. Open the Content tab and add a notecards (you will use this notecard later on to test the server). In the Content tab click New Script and replace the Hello Avatar script with the Server Prim Script. Save the script and you will find the UUID (unique User IDentifier) in Local Chat. Copy this UUID to your clipboard (Ctrl C).
3. Re-edit the object “Child” and open in the Content tab the Child Prim script. Replace the UUID you find in the script with the UUID of your “Server” (Ctrl V). Save the Child Prim Script.
4. To test the Server, touch the object you named “Server”. A blue dialogue will open and will say something like “[Objectname] owned by [Ownername] has given you an item named [Itemname], followed by the SLURL address.
5. Replace the content of the “Server” with the objects you want to give away. Store the Server Prim on a safe place on land you own (or paid the rent for).
6. Design the Child prim to your needs and start your distribution.

NOTE
——-
Once the Server Prim is rezzed and obtained its UUID key you CANNOT take the server into your inventory. If you do so and rerezz the server, the server will obtain a new UUID, which means you have to update ALL the child prims.
Though, you can MOVE the server over your land, or right-click the server and select WEAR to one of your hands. After teleporting or flying you must DROP the server. Do NOT DETACH or the server will go into your inventory and its UUID will be lost.
This Server Giver is FREE, keep it that way.

Enjoy
Adalace Jewell
Server Prim Script

 

// This is not a vendor server. It only GIVES items you put inside the server prim
 
// Once the Server is rezzed and obtained its UUID key you CANNOT take the server into your inventory. If you do so and rerezz the server, the server will obtain a new UUID, which means you have to update ALL the child prims.
 
// Though, you can MOVE the server over your land, or right-click the server and select WEAR to one of your hands. After teleporting or flying you must DROP the server. Do NOT DETACH or the server will go into your inventory and its UUID will be lost.
 
// FREE DISTRIBUTION, keep it that way
 
// Author: unknown
// Script Retrieved from Free SL Scripts at http://www.gendersquare.org/sl
 
string NewsServerKey = "";
 
integer a;
integer b;
string objectname;
list invent_types = [INVENTORY_BODYPART,INVENTORY_SCRIPT,INVENTORY_LANDMARK,INVENTORY_NOTECARD,INVENTORY_CLOTHING,INVENTORY_OBJECT,INVENTORY_SOUND,INVENTORY_TEXTURE];
integer type;
integer typecount;
 
default
{
     on_rez(integer i)
     {
          llResetScript();
     }
 
     state_entry()
     {
          NewsServerKey = llGetKey();
          llSetObjectDesc(NewsServerKey);
          llSetText(" ", <0,1,0>,1.0);
          llOwnerSay(llGetObjectName() + "\n"+ NewsServerKey);
          llSetTimerEvent(2.5);
     }
 
     touch_start(integer total_number)
     {
          NewsServerKey = llGetKey();
          llSetText("put name of server here ", <1 ,1,1>,1.0);
          llInstantMessage(llDetectedKey(0), "My Server Key is: " + NewsServerKey);
     }
 
     email(string time, string address, string subj, string message, integer num_left)
     {
          key target = subj;
            if (target == llGetOwner())
          {
               llOwnerSay("Touch received on a client prim from you.");
               //return; // uncomment if you want to receive copies of the server content yourself
          }
 
          integer total_number = 1;
          integer i;
          for (i=0;i  0)
                    {
                         for (b=0; b ,1.0);
    }
    touch_start(integer total_number)
    {
    llEmail(NewsTargetKey + "@lsl.secondlife.com", llDetectedKey(0), "");
    }
}