// ===================================================================== // Temporary Rezzer ยท step 1 of 2 // skimi3d script library // https://grid.skimi3d.com/scripts/temporary-rezzer // // Puts something out, and takes it away again. The demo house at a // stall, the marquee for tonight only, the target on a shooting range, // the maze that rebuilds itself. // // It needs the other half. What it rezzes must contain "Vanisher", the // second script in this kit, or it will sit there for ever: nothing // can delete an object from outside it, so the thing being rezzed has // to be willing to go. // // Plain LSL. // ===================================================================== // --------------------------------------------------------------------- // Settings // --------------------------------------------------------------------- // What to rez, by name, out of this prim's Contents. Left empty it uses // the first object it finds. string WHAT = ""; // Where it appears, as metres from this prim, along the region's axes: // X east, Y north, Z up. It cannot be more than ten metres away; that // is the platform's limit, not this script's. vector WHERE = <0.0, 2.0, 0.0>; // Minutes before it is called back. 0.0 means it stays until somebody // touches the rezzer again. float MINUTES = 10.0; // Floating words above the rezzer. Empty for none. string LABEL = "Touch to put one out"; vector LABEL_COLOUR = <1.0, 1.0, 1.0>; // Only one at a time: touching again calls the old one back before // putting a new one out. With this off, every touch adds another, which // is how a stall ends up with forty houses on it. integer ONE_AT_A_TIME = TRUE; // Who may use it. 0 = everyone, 1 = only the owner, 2 = same group. integer WHO_MAY_USE = 1; // --------------------------------------------------------------------- // Everything below here is the machinery // --------------------------------------------------------------------- // The word the rezzer says and the Vanisher listens for. Both halves of // the kit have to agree on this number and this word. Change them // together or not at all. integer CHANNEL = -70714; string GO_AWAY = "vanish"; integer gOut = FALSE; string findObject() { if (WHAT != "") return WHAT; if (llGetInventoryNumber(INVENTORY_OBJECT) > 0) { return llGetInventoryName(INVENTORY_OBJECT, 0); } return ""; } callBack() { // Said to the whole region rather than to one object, on a channel // nobody types on. That way it reaches whatever is out there even // if the rezzer has forgotten it, which is what happens after a // region restart. llRegionSay(CHANNEL, GO_AWAY); gOut = FALSE; llSetTimerEvent(0.0); } putOut() { string what = findObject(); if (what == "") { llOwnerSay("I have no object in my Contents to put out."); return; } if (llGetInventoryType(what) != INVENTORY_OBJECT) { llOwnerSay("There is no object called \"" + what + "\" in my Contents."); return; } if (llVecMag(WHERE) > 10.0) { llOwnerSay("WHERE is more than ten metres away, and nothing can be rezzed further than that. Move me closer to where it should stand."); return; } llRezObject(llGetPos() + WHERE, ZERO_VECTOR, ZERO_VECTOR, llGetRot(), 0); gOut = TRUE; if (MINUTES > 0.0) llSetTimerEvent(MINUTES * 60.0); } integer mayUse(key who) { if (WHO_MAY_USE == 1) return who == llGetOwner(); if (WHO_MAY_USE == 2) return llSameGroup(who); return TRUE; } default { state_entry() { llSetText(LABEL, LABEL_COLOUR, 1.0); // Anything left standing from before this script started is // not ours to keep track of, so it is sent away first. callBack(); } touch_start(integer total) { key who = llDetectedKey(0); if (!mayUse(who)) { llRegionSayTo(who, 0, "This one is not yours to use."); return; } if (gOut && ONE_AT_A_TIME) { callBack(); return; } putOut(); } timer() { callBack(); } on_rez(integer start) { llResetScript(); } }