ARES-SDK/ARES/application/instructor.lsl

200 lines
6.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* =========================================================================
*
* Nanite Systems Advanced Research Encapsulation System
*
* Copyright (c) 20252026 Nanite Systems Corporation
*
* =========================================================================
*
* Instructor Application
*
* This program is covered under the terms of the ARES Software Copyright
* License, Section 3 (ASCL-iii). It may be redistributed or used as the
* basis of commercial, closed-source products so long as steps are taken
* to ensure proper attribution as defined in the text of the license.
*
* To see the full text of the ASCL, type 'help license' on any standard
* ARES distribution, or visit http://nanite-systems.com/ASCL for the
* current version.
*
* DISCLAIMER
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS
* IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
* DAMAGES HOWEVER CAUSED ON ANY THEORY OF LIABILITY ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* =========================================================================
*
*/
#include <ARES/a>
#include <ARES/api/interface.consts.h.lsl>
#define CLIENT_VERSION "1.0.0"
#define CLIENT_VERSION_TAGS "release"
#define DEFAULT_INTERVAL 30
#define DEFAULT_ANCHOR CLADDING_BACKDROP
integer enabled = FALSE;
integer interval = DEFAULT_INTERVAL;
string section = "instruction";
integer random = FALSE;
integer anchor = DEFAULT_ANCHOR;
integer offset = 0;
main(integer src, integer n, string m, key outs, key ins, key user) {
if(n == SIGNAL_INVOKE) {
list argv = split(m, " ");
integer argc = count(argv);
string msg = "";
string action = gets(argv, 1);
if(argc == 1 || action == "help") {
msg = "Usage: " + PROGRAM_NAME + " ...\n\n "
+ PROGRAM_NAME + " help: this message\n "
+ PROGRAM_NAME + " anchor <n>: set anchor prim (currently: " + (string)anchor + "); 0 for chat\n "
+ PROGRAM_NAME + " on|off|toggle: enable/disable/toggle instructor (currently: " + gets(["off", "on"], enabled) + ")\n "
+ PROGRAM_NAME + " interval <n>: set interval to <n> sec (currently: " + (string)interval + " sec)\n "
+ PROGRAM_NAME + " random|sequential: set random message selection on/off (currently: " + gets(["off", "on"], random) + ")\n "
+ PROGRAM_NAME + " from <section>: use LSD:<section> as input (currently: " + section + ")"
;
} else if(action == "anchor") {
setdbl("instructor", ["anchor"], (string)(anchor = (integer)gets(argv, 2)));
if(anchor < 0)
anchor = 0;
} else if(action == "on") {
setdbl("instructor", ["enabled"], (string)(enabled = TRUE));
set_timer("instruct", interval);
} else if(action == "off") {
setdbl("instructor", ["enabled"], (string)(enabled = FALSE));
set_timer("instruct", 0);
} else if(action == "toggle") {
setdbl("instructor", ["enabled"], (string)(enabled = !enabled));
if(enabled)
set_timer("instruct", interval);
else
set_timer("instruct", 0);
} else if(action == "interval") {
integer new_interval = (integer)gets(argv, 2);
if(new_interval >= 6) {
setdbl("instructor", ["interval"], (string)(interval = new_interval));
if(enabled)
set_timer("instruct", interval);
} else {
msg = "Interval must be at least 6 sec. Use '@" + PROGRAM_NAME + " off' to disable instruction.";
}
} else if(action == "random") {
setdbl("instructor", ["random"], (string)(random = TRUE));
} else if(action == "sequential") {
setdbl("instructor", ["random"], (string)(random = FALSE));
} else if(action == "from") {
string new_section = gets(argv, 2);
if(llOrd(llLinksetDataRead(new_section), 0) == 0x5b) { // '['
setdbl("instructor", ["section"], section = new_section);
} else {
msg = "Section '" + new_section + "' does not contain a JSON array.";
}
}
if(msg != "")
print(outs, user, msg);
} else if(n == SIGNAL_INIT) {
#ifdef DEBUG
echo("[" + PROGRAM_NAME + "] init event");
#endif
enabled = (integer)getdbl("instructor", ["enabled"]);
random = (integer)getdbl("instructor", ["random"]);
interval = (integer)getdbl("instructor", ["interval"]);
string raw_anchor = getdbl("instructor", ["anchor"]);
if(raw_anchor == JSON_INVALID) {
setdbl("instructor", ["anchor"], (string)(anchor = DEFAULT_ANCHOR));
} else {
anchor = (integer)raw_anchor;
}
if(anchor < 0)
anchor = 0;
section = getdbl("instructor", ["section"]);
if(interval == 0)
setdbl("instructor", ["interval"], (string)(interval = DEFAULT_INTERVAL));
if(enabled)
set_timer("instruct", interval);
} else if(n == SIGNAL_TIMER) {
if(enabled) {
integer line_count = count(js2list(llLinksetDataRead(section)));
if(!line_count) {
echo("[" + PROGRAM_NAME + "] no usable data in " + section + "; please fix");
return;
}
if(random)
offset = (integer)llFrand(0x7fffffff) % line_count;
else
offset = (offset + 1) % line_count;
string message = getdbl(section, [offset]);
if(!anchor) {
echo(getdbl(section, [offset]));
} else {
vector color = getv(getp(2, [PRIM_COLOR, 1]), 0);
float fade = 0;
while(fade < 1.0) {
if(fade >= 0.9375)
fade = 1.0;
setp(anchor, [
PRIM_TEXT, message + "\n \n \n ", color, fade
]);
fade += 0.0625;
llSleep(0.022);
}
fade = 1.0;
llSleep(interval * 0.5 - 2);
while(fade > 0.0) {
if(fade < 0.0625)
fade = 0.0;
setp(anchor, [
PRIM_TEXT, message + "\n \n \n ", color, fade
]);
fade -= 0.0625;
llSleep(0.022);
}
setp(anchor, [
PRIM_TEXT, "", ZV, 0
]);
}
} else {
set_timer("instruct", 0);
}
} else if(n == SIGNAL_UNKNOWN_SCRIPT) {
echo("[" + PROGRAM_NAME + "] failed to run '" + m + "' (kernel could not find the program specified)");
} else {
echo("[" + PROGRAM_NAME + "] unimplemented signal " + (string)n + ": " + m);
}
}
#include <ARES/program>