/////START SCRIPT //// COMPONET // Builders' Buddy 1.0 (Component Pieces) // // by Newfie Pendragon, March 2006 // // This script is distributed with permission that it may be used in // any way, or may be further modified/included in resale items. // HOWEVER, if this script is used as part of a for-sale product, // it is required that appropriate credit be given to Newfie for // the script (or portions used in derivatives). That's a fair price // in exchange for unlimited use of this script, dontcha think? //INSTRUCTIONS //(These instructions use channel 1234 in the examples, but can be // changed further down in the code to whatever channel you wish.) // // This is the *Component Piece* half of the Builders' Buddy system. // Drop it into each 'piece' of the building. Drop the Base Prim Script // into the prim that will be the container/box that will be used to // store the building once completed. It can be in each individual // prim, but if you link as much as possible (and put the script in the link // set), it'll be much more neighbourly and less strain on the sim. // // QUICK USE: // - Drop this script in the Base. // - Drop the "Component" Script in each building part. // - Type: /12345 RECORD // - Take all building parts into inventory // - Drag building parts from inventory into Base Prim // - Type /12345 BUILD // // OTHER COMMANDS // - To reposition, move/rotate Base Prim Type: /12345 MOVE // - To lock into position (removes scripts) Type: /12345 DONE // - To delete building pieces: /12345 CLEAN ////////////////////////////////////////////////////////////////////////////////////////// // Configurable Settings integer PRIMCHAN = 12346; //Channel used by Base Prim to talk to Component Prims; // This must match in both scripts ////////////////////////////////////////////////////////////////////////////////////////// // Runtime Variables (Dont need to change below here unless making a derivative) vector vOffset; rotation rRotation; //////////////////////////////////////////////////////////////////////////////// string first_word(string In_String, string Token) { //This routine searches for the first word in a string, // and returns it. If no word boundary found, returns // the whole string. if(Token == "") Token = " "; integer pos = llSubStringIndex(In_String, Token); //Found it? if( pos >= 1 ) return llGetSubString(In_String, 0, pos - 1); else return In_String; } //////////////////////////////////////////////////////////////////////////////// string other_words(string In_String, string Token) { //This routine searches for the other-than-first words in a string, // and returns it. If no word boundary found, returns // the an empty string. if( Token == "" ) Token = " "; integer pos = llSubStringIndex(In_String, Token); //Found it? if( pos >= 1 ) return llGetSubString(In_String, pos + 1, llStringLength(In_String)); else return ""; } ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// default { ////////////////////////////////////////////////////////////////////////////////////////// state_entry() { //Open up the listener llListen(PRIMCHAN, "", NULL_KEY, ""); } ////////////////////////////////////////////////////////////////////////////////////////// on_rez(integer iStart) { //Set the channel to what's specified if( iStart != 0 ) { PRIMCHAN = iStart; state reset_listeners; } } ////////////////////////////////////////////////////////////////////////////////////////// listen(integer iChan, string sName, key kID, string sText) { string sCmd = llToUpper(first_word(sText, " ")); if( sCmd == "RECORD" ) { sText = other_words(sText, " "); list lParams = llParseString2List(sText, [ "|" ], []); vector vBase = (vector)llList2String(lParams, 0); rotation rBase = (rotation)llList2String(lParams, 1); vOffset = llGetPos() - vBase; rRotation = llGetRot() / rBase; llOwnerSay("Recorded position."); return; } ////////////////////////////////////////////////////////////////////////////////////////// if( sCmd == "MOVE" ) { //Calculate our destination position sText = other_words(sText, " "); list lParams = llParseString2List(sText, [ "|" ], []); vector vBase = (vector)llList2String(lParams, 0); rotation rBase = (rotation)llList2String(lParams, 1); //Calculate our destination position vector vDestPos = (vOffset * rBase) + vBase; rotation rDestRot = rRotation * rBase; llOwnerSay("Pos: " + (string)vDestPos + ", Rot: " + (string)rDestRot); integer i = 0; vector vLastPos = ZERO_VECTOR; while( (i < 25) && (llGetPos() != vDestPos) ) { //If we're not there.... if( llGetPos() != vDestPos ) { //We may be stuck on the ground... //Did we move at all compared to last loop? if( llGetPos() == vLastPos ) { //Yep, stuck...move straight up 10m (attempt to dislodge) llSetPos(llGetPos() + <0, 0, 10.0>); } else { //Record our spot for 'stuck' detection vLastPos = llGetPos(); } } i++; //Try to move to destination llSetPos(vDestPos); llSleep(0.1); } //Set rotation llSetRot(rDestRot); return; } ////////////////////////////////////////////////////////////////////////////////////////// if( sCmd == "DONE" ) { //We are done, remove script llRemoveInventory(llGetScriptName()); return; } ////////////////////////////////////////////////////////////////////////////////////////// if( sCmd == "CLEAN" ) { //Clean up llDie(); return; } } } ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// state reset_listeners { ////////////////////////////////////////////////////////////////////////////////////////// state_entry() { state default; } } ///////END SCRIPT COMPONET