// ===================================================================== // Light Switch // skimi3d script library // https://grid.skimi3d.com/scripts/light-switch // // A lamp you can switch. Touch it and it lights the room, glows, and // turns its own shade bright so it looks lit rather than merely // illuminating; touch it again and all three go out together. // // The three parts matter. A light with no glow is a room that brightens // around a dark lamp. Glow with no light is a lamp that shines on // nothing. Doing them separately is how most lamps end up looking // wrong. // // Plain LSL. // ===================================================================== // --------------------------------------------------------------------- // Settings // --------------------------------------------------------------------- // The colour of the light it casts. <1.0, 0.85, 0.6> is a warm bulb, // <1.0, 1.0, 1.0> is white, <0.6, 0.75, 1.0> is moonlight. vector COLOUR = <1.0, 0.85, 0.6>; // How bright, from 0.0 to 1.0. float INTENSITY = 0.7; // How far the light reaches, in metres. Up to 20. float RADIUS = 8.0; // How quickly it fades with distance, from 0.0 to 1.0. Higher fades // faster and keeps the light close to the lamp. float FALLOFF = 0.6; // Which face of the prim is the shade or the bulb, the part that should // look lit. -1 means every face. Use the number of a single face if // only the glass should light up and the metal should not. integer FACE = -1; // How much the lit face glows, from 0.0 to 1.0. A little goes a long // way; 0.15 reads as lit, 0.5 reads as a fault. float GLOW = 0.15; // Make the lit face ignore the region's own light, so it stays bright // at midnight. This is what sells a lamp as switched on. integer FULLBRIGHT = TRUE; // Is it already on when it is rezzed? integer START_ON = TRUE; // Who may switch it. 0 = everyone, 1 = only the owner, 2 = only people // wearing the same group tag. integer WHO_MAY_SWITCH = 0; // Name of a sound in the lamp's Contents, played on each click. Leave // empty for a silent switch. string SOUND = ""; float VOLUME = 0.4; // --------------------------------------------------------------------- // Everything below here is the machinery // --------------------------------------------------------------------- integer gOn = FALSE; // One write, not three. // // OpenSim gathers object updates and sends them in bundles. Setting the // light, then the glow, then the brightness in three calls can reach a // viewer as three separate flickers. Sent together they arrive as one // change, and the lamp simply comes on. switchTo(integer on) { float glow = 0.0; integer bright = FALSE; if (on) { glow = GLOW; bright = FULLBRIGHT; } list p = [PRIM_POINT_LIGHT, on, COLOUR, INTENSITY, RADIUS, FALLOFF, PRIM_GLOW, FACE, glow]; // PRIM_FULLBRIGHT wants a plain on or off, and only when the lamp // is meant to use it at all. A lamp with FULLBRIGHT switched off in // the settings should never have its faces touched. if (FULLBRIGHT) p += [PRIM_FULLBRIGHT, FACE, bright]; llSetLinkPrimitiveParamsFast(LINK_THIS, p); gOn = on; } integer maySwitch(key who) { if (WHO_MAY_SWITCH == 1) return who == llGetOwner(); if (WHO_MAY_SWITCH == 2) return llSameGroup(who); return TRUE; } default { state_entry() { switchTo(START_ON); } touch_start(integer total) { key who = llDetectedKey(0); if (!maySwitch(who)) { llRegionSayTo(who, 0, "This one is not yours to switch."); return; } if (SOUND != "") { if (llGetInventoryType(SOUND) == INVENTORY_SOUND) { llPlaySound(SOUND, VOLUME); } else { llOwnerSay("There is no sound called \"" + SOUND + "\" in my Contents."); } } switchTo(!gOn); } on_rez(integer start) { // A rezzed copy carries the light state it was taken in, which // may not be the one the settings ask for. Say it again. switchTo(START_ON); } }