switch_region.lsl 24 KB

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