switch.lsl 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. // :SHOW:1
  2. // :CATEGORY:Light
  3. // :NAME:Rene Free Lighting System
  4. // :AUTHOR:Rene10957 Resident
  5. // :KEYWORDS: light,lamp,lighting light
  6. // :CREATED:2015-06-11 14:41:45
  7. // :EDITED:2016-03-30 20:29:27
  8. // :ID:1079
  9. // :NUM:1784
  10. // :REV:2.1
  11. // :WORLD:Opensim
  12. // :DESCRIPTION:
  13. // Light Switch
  14. // :CODE:
  15. // :LICENSE: CC0 (Public Domain)
  16. // Rene's Free Lighting System - Light Switch
  17. //
  18. // Author: Rene10957 Resident
  19. // Date: 31-05-2015
  20. // License: CC0 (Public Domain).
  21. // To the extent possible under law, Rene10957 has waived all copyright and related or neighboring rights.
  22. // For more information, see http://creativecommons.org/publicdomain/zero/1.0/.
  23. string title = "Light Switch"; // title
  24. string version = "2.1"; // version
  25. integer linkSet = TRUE; // LINKSET mode
  26. // Constants
  27. integer _PUBLIC_ = 1; // public access bit
  28. integer _GROUP_ = 2; // group access bit
  29. integer _OWNER_ = 4; // owner access bit
  30. integer _GRPOWN_ = 6; // group + owner
  31. integer switchChannel = -10957; // switch channel
  32. float maxRed = 1.0; // max. red
  33. float maxGreen = 1.0; // max. green
  34. float maxBlue = 1.0; // max. blue
  35. float maxRadius = 20.0; // max. light radius
  36. float maxFalloff = 2.0; // max. light falloff
  37. float maxGlow = 1.0; // max. prim glow
  38. float maxAlpha = 1.0; // max. prim alpha
  39. string configPrefix = "config"; // prefix for configuration notecards
  40. string configSeparator = ":"; // separator between prefix and name
  41. string defNotecard = "Default"; // default notecard
  42. // Notecard variables
  43. integer verbose = FALSE; // show more/less info during startup
  44. integer switchAccess; // access level for switch
  45. integer menuAccess; // access level for menu
  46. integer msgNumber; // number part of incoming link messages
  47. string msgSwitch; // string part of incoming link message: switch (on/off)
  48. string msgOn; // string part of incoming link message: switch on
  49. string msgOff; // string part of incoming link message: switch off
  50. string msgMenu; // string part of incoming link message: show menu
  51. integer percent; // increase/decrease percentage for +/- buttons
  52. integer changePrimColor = FALSE; // TRUE = prim color changes with light color, FALSE = white
  53. integer changeParticleColor = FALSE; // TRUE = particle color changes with light color, FALSE = white
  54. integer particleInc; // increase/decrease percentage for particle effect (menu)
  55. string particleTexture; // texture UUID for particle effect
  56. integer particleMenu = FALSE; // TRUE = "On/Off" replaced by "Particles" (particle menu)
  57. integer notecardMenu = FALSE; // TRUE = "On/Off" replaced by "Presets" (notecard menu)
  58. string extButton; // "On/Off" replaced by button text (sends link message)
  59. integer extNumber; // number part of outgoing link message
  60. integer lightGroups = FALSE; // TRUE = use prim description for light groups, FALSE = ignore prim description
  61. string faces; // color/glow/fullbright on all faces (ALL_SIDES = -1), one face or CSV list
  62. integer baseIntensity; // base for light intensity
  63. // Notecard variables: menu defaults
  64. vector defColor; // default color (R,G,B)
  65. vector defColorOff; // default color (R,G,B) when OFF
  66. integer defAlpha; // default prim alpha
  67. integer defAlphaOff; // default prim alpha when OFF
  68. integer defIntensity; // default light intensity
  69. integer defRadius; // default light radius
  70. integer defFalloff; // default light falloff
  71. integer defGlow; // default prim glow
  72. integer defFullbright = FALSE; // default fullbright
  73. integer defParticleSize; // default particle size
  74. // Variables
  75. key owner; // object owner
  76. key user; // key of last avatar to touch object
  77. list notecardButtons; // list of notecards in inventory
  78. string notecard; // notecard name
  79. integer line; // notecard line
  80. integer loading = FALSE; // notecard loading
  81. integer menuChannel; // main menu channel
  82. integer colorChannel; // color menu channel
  83. integer particleChannel; // particle menu channel
  84. integer notecardChannel; // notecard menu channel
  85. integer menuHandle; // handle for main menu listener
  86. integer colorHandle; // handle for color menu listener
  87. integer particleHandle; // handle for particle menu listener
  88. integer notecardHandle; // handle for notecard menu listener
  89. integer on = FALSE; // on-off switch
  90. integer particles = TRUE; // particles on/off
  91. integer perRed; // percent red
  92. integer perGreen; // percent green
  93. integer perBlue; // percent blue
  94. integer perAlpha; // percent prim alpha
  95. integer perRedOff; // percent red when OFF
  96. integer perGreenOff; // percent green when OFF
  97. integer perBlueOff; // percent blue when OFF
  98. integer perAlphaOff; // percent prim alpha when OFF
  99. integer perIntensity; // percent light intensity
  100. integer perRadius; // percent light radius
  101. integer perFalloff; // percent light falloff
  102. integer perGlow; // percent prim glow
  103. integer fullbright = TRUE; // fullbright
  104. // Functions
  105. list orderButtons(list buttons)
  106. {
  107. return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) +
  108. llList2List(buttons, -12, -10);
  109. }
  110. discoverNotecards()
  111. {
  112. llSetText("Discovering notecards...", <1,1,1>, 1.0);
  113. notecardButtons = [];
  114. integer i;
  115. integer pos;
  116. integer number = llGetInventoryNumber(INVENTORY_NOTECARD);
  117. string name;
  118. string prefix;
  119. string suffix;
  120. for (i = 0; i < number; ++i) {
  121. name = llGetInventoryName(INVENTORY_NOTECARD, i);
  122. pos = llSubStringIndex(name, configSeparator);
  123. if (pos > -1) {
  124. prefix = llGetSubString(name, 0, pos - 1);
  125. suffix = llGetSubString(name, pos + 1, -1);
  126. if (prefix == configPrefix && suffix != defNotecard && llGetListLength(notecardButtons) < 10)
  127. notecardButtons += suffix;
  128. }
  129. }
  130. notecardButtons = llListSort(notecardButtons, 1, TRUE); // sort ascending
  131. if (llGetInventoryType(configPrefix + configSeparator + defNotecard) == INVENTORY_NOTECARD)
  132. notecardButtons += defNotecard;
  133. if (llGetListLength(notecardButtons) > 0) {
  134. notecardButtons += "Main menu";
  135. notecardButtons = orderButtons(notecardButtons); // reverse row order
  136. }
  137. llSetText("", ZERO_VECTOR, 0.0);
  138. }
  139. integer accessGranted(key user, integer access)
  140. {
  141. integer bitmask = _PUBLIC_;
  142. if (user == owner) bitmask += _OWNER_;
  143. if (llSameGroup(user)) bitmask += _GROUP_;
  144. return (bitmask & access);
  145. }
  146. integer checkAccess(string par, string val)
  147. {
  148. if (llToLower(val) == "public") return _PUBLIC_;
  149. if (llToLower(val) == "group") return _GROUP_;
  150. if (llToLower(val) == "owner") return _OWNER_;
  151. if (llToLower(val) == "group+owner") return _GRPOWN_;
  152. llWhisper(0, "[Notecard] " + par + " out of range, corrected to PUBLIC");
  153. return _PUBLIC_;
  154. }
  155. integer checkInt(string par, integer val, integer min, integer max)
  156. {
  157. if (val < min || val > max) {
  158. if (val < min) val = min;
  159. else if (val > max) val = max;
  160. llWhisper(0, "[Notecard] " + par + " out of range, corrected to " + (string)val);
  161. }
  162. return val;
  163. }
  164. vector checkVector(string par, vector val)
  165. {
  166. if (val == ZERO_VECTOR) {
  167. val = <100,100,100>;
  168. llWhisper(0, "[Notecard] " + par + " out of range, corrected to " + (string)val);
  169. }
  170. return val;
  171. }
  172. integer checkYesNo(string par, string val)
  173. {
  174. if (llToLower(val) == "yes") return TRUE;
  175. if (llToLower(val) == "no") return FALSE;
  176. llWhisper(0, "[Notecard] " + par + " out of range, corrected to NO");
  177. return FALSE;
  178. }
  179. string checkKey(string par, string val)
  180. {
  181. if ((key)val) return val;
  182. if (val == "") return val;
  183. llWhisper(0, "[Notecard] " + par + " out of range (not a valid key)");
  184. return "";
  185. }
  186. string truncMenuButton(string par, string val)
  187. {
  188. string trunc = llBase64ToString(llGetSubString(llStringToBase64(val), 0, 31));
  189. if (val != trunc) llWhisper(0, "[Notecard] " + par + " will be truncated to 24 bytes");
  190. return trunc;
  191. }
  192. loadNotecard()
  193. {
  194. verbose = TRUE;
  195. switchAccess = _PUBLIC_;
  196. menuAccess = _PUBLIC_;
  197. msgNumber = 10957;
  198. msgSwitch = "switch";
  199. msgOn = "on";
  200. msgOff = "off";
  201. msgMenu = "menu";
  202. percent = 10;
  203. changePrimColor = TRUE;
  204. changeParticleColor = TRUE;
  205. particleTexture = "";
  206. particleMenu = FALSE;
  207. notecardMenu = FALSE;
  208. extButton = "";
  209. extNumber = 10958;
  210. lightGroups = FALSE;
  211. faces = "-1";
  212. baseIntensity = 100;
  213. defColor = <100,100,100>;
  214. defColorOff = <100,100,100>;
  215. defAlpha = 100;
  216. defAlphaOff = 100;
  217. defIntensity = 100;
  218. defRadius = 50;
  219. defFalloff = 40;
  220. defGlow = 0;
  221. defFullbright = TRUE;
  222. defParticleSize = 20;
  223. line = 0;
  224. if (llGetInventoryType(notecard) == INVENTORY_NOTECARD) {
  225. loading = TRUE;
  226. llSetText("Loading notecard...", <1,1,1>, 1.0);
  227. llGetNotecardLine(notecard, line);
  228. }
  229. else {
  230. reset();
  231. particleInc = 999; // reset particle size in plugin script
  232. sendMessage(getGroup());
  233. if (verbose) {
  234. llWhisper(0, "Notecard \"" + notecard + "\" not found or empty, using defaults");
  235. llWhisper(0, "Touch to turn light on or off");
  236. llWhisper(0, "Long touch to show menu");
  237. if (linkSet) llWhisper(0, title + " " + version + "-LINKSET ready");
  238. else llWhisper(0, title + " " + version + "-REGION ready");
  239. }
  240. }
  241. }
  242. readNotecard (string ncLine)
  243. {
  244. string ncData = llStringTrim(ncLine, STRING_TRIM);
  245. if (llStringLength(ncData) > 0 && llGetSubString(ncData, 0, 0) != "#") {
  246. list ncList = llParseString2List(ncData, ["=","#"], []); // split into parameter, value, comment
  247. string par = llStringTrim(llList2String(ncList, 0), STRING_TRIM);
  248. string val = llStringTrim(llList2String(ncList, 1), STRING_TRIM);
  249. string lcpar = llToLower(par);
  250. if (lcpar == "verbose") verbose = checkYesNo(par, val);
  251. else if (lcpar == "switchaccess") switchAccess = checkAccess(par, val);
  252. else if (lcpar == "menuaccess") menuAccess = checkAccess(par, val);
  253. else if (lcpar == "msgnumber") msgNumber = (integer)val;
  254. else if (lcpar == "msgswitch") msgSwitch = truncMenuButton(par, val);
  255. else if (lcpar == "msgon") msgOn = truncMenuButton(par, val);
  256. else if (lcpar == "msgoff") msgOff = truncMenuButton(par, val);
  257. else if (lcpar == "msgmenu") msgMenu = truncMenuButton(par, val);
  258. else if (lcpar == "menupercent") percent = checkInt(par, (integer)val, 1, 100);
  259. else if (lcpar == "changeprimcolor") changePrimColor = checkYesNo(par, val);
  260. else if (lcpar == "changeparticlecolor") changeParticleColor = checkYesNo(par, val);
  261. else if (lcpar == "particletexture") particleTexture = checkKey(par, val);
  262. else if (lcpar == "particlemenu") particleMenu = checkYesNo(par, val);
  263. else if (lcpar == "notecardmenu") notecardMenu = checkYesNo(par, val);
  264. else if (lcpar == "extbutton") extButton = truncMenuButton(par, val);
  265. else if (lcpar == "extnumber") extNumber = (integer)val;
  266. else if (lcpar == "lightgroups") lightGroups = checkYesNo(par, val);
  267. else if (lcpar == "faces") faces = truncMenuButton(par, val);
  268. else if (lcpar == "baseintensity") baseIntensity = checkInt(par, (integer)val, 1, 100);
  269. else if (lcpar == "coloron") defColor = checkVector(par, (vector)val);
  270. else if (lcpar == "coloroff") defColorOff = checkVector(par, (vector)val);
  271. else if (lcpar == "alphaon") defAlpha = checkInt(par, (integer)val, 0, 100);
  272. else if (lcpar == "alphaoff") defAlphaOff = checkInt(par, (integer)val, 0, 100);
  273. else if (lcpar == "intensity") defIntensity = checkInt(par, (integer)val, 0, 100);
  274. else if (lcpar == "radius") defRadius = checkInt(par, (integer)val, 0, 100);
  275. else if (lcpar == "falloff") defFalloff = checkInt(par, (integer)val, 0, 100);
  276. else if (lcpar == "glow") defGlow = checkInt(par, (integer)val, 0, 100);
  277. else if (lcpar == "fullbright") defFullbright = checkYesNo(par, val);
  278. else if (lcpar == "particlesize") defParticleSize = checkInt(par, (integer)val, 1, 100);
  279. else llWhisper(0, "Unknown parameter in notecard line " + (string)(line + 1) + ": " + par);
  280. }
  281. line++;
  282. llGetNotecardLine(notecard, line);
  283. }
  284. menuDialog (key id)
  285. {
  286. string strOn = "OFF"; if (on) strOn = "ON";
  287. string strLinkSet = "REGION"; if (linkSet) strLinkSet = "LINKSET";
  288. string strFullbright = "NO"; if (fullbright) strFullbright = "YES";
  289. string strButton = "On/Off"; if (particleMenu) strButton = "Particles";
  290. else if (notecardMenu) strButton = "Presets";
  291. else if (extButton) strButton = extButton;
  292. menuChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
  293. llListenRemove(menuHandle);
  294. menuHandle = llListen(menuChannel, "", "", "");
  295. llSetTimerEvent(0);
  296. llSetTimerEvent(300);
  297. llDialog(id, title + " " + version +
  298. "\n\nIntensity: " + (string)perIntensity + "%\t\tState: " + strOn +
  299. "\nRadius: " + (string)perRadius + "%\t\tFullbright: " + strFullbright +
  300. "\nFalloff: " + (string)perFalloff + "%\t\tMode: " + strLinkSet +
  301. "\nGlow: " + (string)perGlow + "%\t\tGroup: " + getGroup(), [
  302. "-Glow", "+Glow", strButton,
  303. "-Falloff", "+Falloff", "Reset",
  304. "-Radius", "+Radius", "Fullbright",
  305. "-Intensity", "+Intensity", "Color" ],
  306. menuChannel);
  307. }
  308. colorDialog (key id)
  309. {
  310. colorChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
  311. llListenRemove(colorHandle);
  312. colorHandle = llListen(colorChannel, "", "", "");
  313. llSetTimerEvent(0);
  314. llSetTimerEvent(300);
  315. if (on) {
  316. llDialog(id, "Color & Alpha when ON" +
  317. "\n\nRed: " + (string)perRed + "%" +
  318. "\nGreen: " + (string)perGreen + "%" +
  319. "\nBlue: " + (string)perBlue + "%" +
  320. "\nAlpha: " + (string)perAlpha + "%", [
  321. "-Alpha", "+Alpha", "Main menu",
  322. "-Blue", "+Blue", "B min/max",
  323. "-Green", "+Green", "G min/max",
  324. "-Red", "+Red", "R min/max" ],
  325. colorChannel);
  326. }
  327. else {
  328. llDialog(id, "Color & Alpha when OFF" +
  329. "\n\nRed: " + (string)perRedOff + "%" +
  330. "\nGreen: " + (string)perGreenOff + "%" +
  331. "\nBlue: " + (string)perBlueOff + "%" +
  332. "\nAlpha: " + (string)perAlphaOff + "%", [
  333. "-Alpha", "+Alpha", "Main menu",
  334. "-Blue", "+Blue", "B min/max",
  335. "-Green", "+Green", "G min/max",
  336. "-Red", "+Red", "R min/max" ],
  337. colorChannel);
  338. }
  339. }
  340. particleDialog (key id)
  341. {
  342. string strLightOn = "OFF"; if (on) strLightOn = "ON";
  343. string strParticlesOn = "OFF"; if (particles) strParticlesOn = "ON";
  344. particleChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
  345. llListenRemove(particleHandle);
  346. particleHandle = llListen(particleChannel, "", "", "");
  347. llSetTimerEvent(0);
  348. llSetTimerEvent(300);
  349. llDialog(id, "Particle effect" +
  350. "\n\nLight: " + strLightOn +
  351. "\nParticles: " + strParticlesOn, [
  352. "Min", "Max", "Main menu",
  353. "-10%", "+10%", "Reset",
  354. "-5%", "+5%", "Part. on/off",
  355. "-1%", "+1%", "Light on/off" ],
  356. particleChannel);
  357. }
  358. notecardDialog (key id)
  359. {
  360. string name = llGetSubString(notecard, llStringLength(configPrefix) + llStringLength(configSeparator), -1);
  361. notecardChannel = (integer)(llFrand(-1000000000.0) - 1000000000.0);
  362. llListenRemove(notecardHandle);
  363. notecardHandle = llListen(notecardChannel, "", "", "");
  364. llSetTimerEvent(0);
  365. llSetTimerEvent(300);
  366. llDialog(id, "Configuration notecards\n\nLoaded notecard: " + name, notecardButtons, notecardChannel);
  367. }
  368. string getGroup()
  369. {
  370. if (!lightGroups) return "None";
  371. string str = llStringTrim(llGetObjectDesc(), STRING_TRIM);
  372. if (llToLower(str) == "(no description)" || str == "") str = "Default";
  373. return str;
  374. }
  375. float percentage (integer per, float num)
  376. {
  377. return num / 100.0 * (float)per;
  378. }
  379. integer min (integer x, integer y)
  380. {
  381. if (x < y) return x; else return y;
  382. }
  383. integer max (integer x, integer y)
  384. {
  385. if (x > y) return x; else return y;
  386. }
  387. reset()
  388. {
  389. perRed = (integer)defColor.x;
  390. perGreen = (integer)defColor.y;
  391. perBlue = (integer)defColor.z;
  392. perRedOff = (integer)defColorOff.x;
  393. perGreenOff = (integer)defColorOff.y;
  394. perBlueOff = (integer)defColorOff.z;
  395. perAlpha = defAlpha;
  396. perAlphaOff = defAlphaOff;
  397. perIntensity = defIntensity;
  398. perRadius = defRadius;
  399. perFalloff = defFalloff;
  400. perGlow = defGlow;
  401. fullbright = defFullbright;
  402. }
  403. sendMessage(string group)
  404. {
  405. vector color;
  406. vector colorOn;
  407. vector colorOff;
  408. float intensity;
  409. float radius;
  410. float falloff;
  411. float alpha;
  412. float glow;
  413. integer fullbr;
  414. vector primColor;
  415. vector particleColor;
  416. integer particlesOn;
  417. colorOn.x = percentage(perRed, maxRed);
  418. colorOn.y = percentage(perGreen, maxGreen);
  419. colorOn.z = percentage(perBlue, maxBlue);
  420. colorOff.x = percentage(perRedOff, maxRed);
  421. colorOff.y = percentage(perGreenOff, maxGreen);
  422. colorOff.z = percentage(perBlueOff, maxBlue);
  423. if (on) {
  424. color = colorOn;
  425. intensity = percentage(perIntensity, (float)baseIntensity / 100.0);
  426. radius = percentage(perRadius, maxRadius);
  427. falloff = percentage(perFalloff, maxFalloff);
  428. alpha = percentage(perAlpha, maxAlpha);
  429. glow = percentage(perGlow, maxGlow);
  430. fullbr = fullbright;
  431. if (changePrimColor) primColor = color;
  432. else primColor = colorOff;
  433. if (changeParticleColor) particleColor = color;
  434. else particleColor = colorOff;
  435. particlesOn = particles;
  436. }
  437. else {
  438. color = colorOff;
  439. alpha = percentage(perAlphaOff, maxAlpha);
  440. glow = 0.0;
  441. fullbr = FALSE;
  442. primColor = color;
  443. particlesOn = FALSE;
  444. }
  445. list msgList = [group, on, color, intensity, radius, falloff, alpha, glow, fullbr,
  446. primColor, particleColor, defParticleSize, particleInc, particleTexture, particlesOn,
  447. "<" + faces + ">", lightGroups];
  448. string msg = llList2CSV(msgList);
  449. particleInc = 0;
  450. if (linkSet) llMessageLinked(LINK_SET, switchChannel, msg, "");
  451. else llRegionSay(switchChannel, msg);
  452. }
  453. default
  454. {
  455. state_entry()
  456. {
  457. owner = llGetOwner();
  458. notecard = configPrefix + configSeparator + defNotecard;
  459. discoverNotecards();
  460. loadNotecard();
  461. }
  462. on_rez(integer start_param)
  463. {
  464. llResetScript();
  465. }
  466. touch_start(integer total_number)
  467. {
  468. llResetTime();
  469. }
  470. touch_end(integer total_number)
  471. {
  472. if (loading) {
  473. llWhisper(0, "Notecard is still loading");
  474. return;
  475. }
  476. user = llDetectedKey(0);
  477. if (llGetTime() > 1.0) {
  478. if (accessGranted(user, menuAccess)) menuDialog(user);
  479. else llInstantMessage(user, "[Menu] Access denied");
  480. }
  481. else {
  482. if (accessGranted(user, switchAccess)) {
  483. on = !on;
  484. sendMessage(getGroup());
  485. }
  486. else llInstantMessage(user, "[Switch] Access denied");
  487. }
  488. }
  489. listen(integer channel, string name, key id, string msg)
  490. {
  491. llSetTimerEvent(0);
  492. if (channel == menuChannel) {
  493. llListenRemove(menuHandle);
  494. if (msg == "-Intensity") perIntensity = max(perIntensity - percent, 0);
  495. else if (msg == "-Radius") perRadius = max(perRadius - percent, 0);
  496. else if (msg == "-Falloff") perFalloff = max(perFalloff - percent, 0);
  497. else if (msg == "-Glow") perGlow = max(perGlow - percent, 0);
  498. else if (msg == "+Intensity") perIntensity = min(perIntensity + percent, 100);
  499. else if (msg == "+Radius") perRadius = min(perRadius + percent, 100);
  500. else if (msg == "+Falloff") perFalloff = min(perFalloff + percent, 100);
  501. else if (msg == "+Glow") perGlow = min(perGlow + percent, 100);
  502. else if (msg == "Color") colorDialog(id);
  503. else if (msg == "Fullbright") fullbright = !fullbright;
  504. else if (msg == "Reset") reset();
  505. else if (msg == "On/Off") on = !on;
  506. else if (msg == "Particles") particleDialog(id);
  507. else if (msg == "Presets") {
  508. if (llGetListLength(notecardButtons) > 0) notecardDialog(id);
  509. else llWhisper(0, "No configuration notecards found");
  510. }
  511. else if (msg == extButton) llMessageLinked(LINK_SET, extNumber, msg, id);
  512. if (msg != "Color" && msg != "Particles" && msg != "Presets" && msg != extButton) {
  513. sendMessage(getGroup());
  514. menuDialog(id);
  515. }
  516. }
  517. else if (channel == colorChannel) {
  518. llListenRemove(colorHandle);
  519. if (on) {
  520. if (msg == "-Red") perRed = max(perRed - percent, 0);
  521. else if (msg == "-Green") perGreen = max(perGreen - percent, 0);
  522. else if (msg == "-Blue") perBlue = max(perBlue - percent, 0);
  523. else if (msg == "-Alpha") perAlpha = max(perAlpha - percent, 0);
  524. else if (msg == "+Red") perRed = min(perRed + percent, 100);
  525. else if (msg == "+Green") perGreen = min(perGreen + percent, 100);
  526. else if (msg == "+Blue") perBlue = min(perBlue + percent, 100);
  527. else if (msg == "+Alpha") perAlpha = min(perAlpha + percent, 100);
  528. else if (msg == "R min/max") { if (perRed) perRed = 0; else perRed = 100; }
  529. else if (msg == "G min/max") { if (perGreen) perGreen = 0; else perGreen = 100; }
  530. else if (msg == "B min/max") { if (perBlue) perBlue = 0; else perBlue = 100; }
  531. else if (msg == "Main menu") menuDialog(id);
  532. }
  533. else {
  534. if (msg == "-Red") perRedOff = max(perRedOff - percent, 0);
  535. else if (msg == "-Green") perGreenOff = max(perGreenOff - percent, 0);
  536. else if (msg == "-Blue") perBlueOff = max(perBlueOff - percent, 0);
  537. else if (msg == "-Alpha") perAlphaOff = max(perAlphaOff - percent, 0);
  538. else if (msg == "+Red") perRedOff = min(perRedOff + percent, 100);
  539. else if (msg == "+Green") perGreenOff = min(perGreenOff + percent, 100);
  540. else if (msg == "+Blue") perBlueOff = min(perBlueOff + percent, 100);
  541. else if (msg == "+Alpha") perAlphaOff = min(perAlphaOff + percent, 100);
  542. else if (msg == "R min/max") { if (perRedOff) perRedOff = 0; else perRedOff = 100; }
  543. else if (msg == "G min/max") { if (perGreenOff) perGreenOff = 0; else perGreenOff = 100; }
  544. else if (msg == "B min/max") { if (perBlueOff) perBlueOff = 0; else perBlueOff = 100; }
  545. else if (msg == "Main menu") menuDialog(id);
  546. }
  547. if (msg != "Main menu") {
  548. sendMessage(getGroup());
  549. colorDialog(id);
  550. }
  551. }
  552. else if (channel == particleChannel) {
  553. llListenRemove(particleHandle);
  554. if (msg == "-1%") particleInc = -1;
  555. else if (msg == "+1%") particleInc = 1;
  556. else if (msg == "-5%") particleInc = -5;
  557. else if (msg == "+5%") particleInc = 5;
  558. else if (msg == "-10%") particleInc = -10;
  559. else if (msg == "+10%") particleInc = 10;
  560. else if (msg == "Min") particleInc = -100;
  561. else if (msg == "Max") particleInc = 100;
  562. else if (msg == "Light on/off") on = !on;
  563. else if (msg == "Part. on/off") particles = !particles;
  564. else if (msg == "Reset") particleInc = 999; // reset particle size
  565. else if (msg == "Main menu") menuDialog(id);
  566. if (msg != "Main menu") {
  567. sendMessage(getGroup());
  568. particleDialog(id);
  569. }
  570. }
  571. else if (channel == notecardChannel) {
  572. llListenRemove(notecardHandle);
  573. if (msg == "Main menu") menuDialog(id);
  574. else {
  575. notecard = configPrefix + configSeparator + msg;
  576. loadNotecard();
  577. }
  578. }
  579. }
  580. link_message(integer sender_number, integer number, string msg, key id)
  581. {
  582. if (number != msgNumber) return;
  583. if (loading) {
  584. llWhisper(0, "Notecard is still loading");
  585. return;
  586. }
  587. if (id) user = id;
  588. else {
  589. llWhisper(0, "A valid avatar key must be provided in the link message");
  590. return;
  591. }
  592. if (msg == msgSwitch) {
  593. if (accessGranted(id, switchAccess)) {
  594. on = !on;
  595. sendMessage(getGroup());
  596. }
  597. else llInstantMessage(id, "[Switch] Access denied");
  598. }
  599. else if (msg == msgOn) {
  600. if (accessGranted(id, switchAccess)) {
  601. if (!on) {
  602. on = TRUE;
  603. sendMessage(getGroup());
  604. }
  605. }
  606. else llInstantMessage(id, "[Switch] Access denied");
  607. }
  608. else if (msg == msgOff) {
  609. if (accessGranted(id, switchAccess)) {
  610. if (on) {
  611. on = FALSE;
  612. sendMessage(getGroup());
  613. }
  614. }
  615. else llInstantMessage(id, "[Switch] Access denied");
  616. }
  617. else if (msg == msgMenu) {
  618. if (accessGranted(id, menuAccess)) menuDialog(id);
  619. else llInstantMessage(id, "[Menu] Access denied");
  620. }
  621. }
  622. dataserver(key req, string data)
  623. {
  624. if (data == EOF) {
  625. defColor.x = checkInt("ColorOn (RED)", (integer)defColor.x, 0, 100);
  626. defColor.y = checkInt("ColorOn (GREEN)", (integer)defColor.y, 0, 100);
  627. defColor.z = checkInt("ColorOn (BLUE)", (integer)defColor.z, 0, 100);
  628. defColorOff.x = checkInt("ColorOff (RED)", (integer)defColorOff.x, 0, 100);
  629. defColorOff.y = checkInt("ColorOff (GREEN)", (integer)defColorOff.y, 0, 100);
  630. defColorOff.z = checkInt("ColorOff (BLUE)", (integer)defColorOff.z, 0, 100);
  631. reset();
  632. particleInc = 999; // reset particle size in plugin script
  633. sendMessage(getGroup());
  634. if (verbose) if (user) {} else {
  635. llWhisper(0, "Touch to turn light on or off");
  636. llWhisper(0, "Long touch to show menu");
  637. if (linkSet) llWhisper(0, title + " " + version + "-LINKSET ready");
  638. else llWhisper(0, title + " " + version + "-REGION ready");
  639. }
  640. loading = FALSE;
  641. llSetText("", ZERO_VECTOR, 0.0);
  642. if (user) notecardDialog(user);
  643. }
  644. else {
  645. readNotecard(data);
  646. }
  647. }
  648. changed(integer change)
  649. {
  650. if (change & CHANGED_INVENTORY) {
  651. user = "";
  652. discoverNotecards();
  653. loadNotecard();
  654. }
  655. }
  656. timer()
  657. {
  658. llSetTimerEvent(0);
  659. llListenRemove(menuHandle);
  660. llListenRemove(colorHandle);
  661. llListenRemove(particleHandle);
  662. llListenRemove(notecardHandle);
  663. }
  664. }