AVsitter/AVsitter2/Plugins/AVsequence/[AV]sequence.lsl

451 lines
14 KiB
Text

/*
* [AV]sequence - Play sequences of poses.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright © the AVsitter Contributors (http://avsitter.github.io)
* AVsitter™ is a trademark. For trademark use policy see:
* https://avsitter.github.io/TRADEMARK.mediawiki
*
* Please consider supporting continued development of AVsitter and
* receive automatic updates and other benefits! All details and user
* instructions can be found at http://avsitter.github.io
*/
string product = "AVsitter™ sequence";
string #version = "2.2";
string main_script = "[AV]sitA";
list SITTERS;
integer DEBUG;
string notecard_name = "[AV]sequence_settings";
integer notecard_line;
key notecard_query;
key notecard_key;
list SEQUENCE_DATA_NAMES;
list SEQUENCE_DATA_ACTIONS;
list SEQUENCE_DATA_DATAS;
string CURRENT_SEQUENCE_NAME;
list CURRENT_SEQUENCE_ACTIONS;
list CURRENT_SEQUENCE_DATAS = [CURRENT_SEQUENCE_NAME]; //OSS::list CURRENT_SEQUENCE_DATAS; // Force error in LSO
integer SEQUENCE_LINKNUMBER = 90210;
integer SEQUENCE_POINTER = -1;
integer sequence_running;
key CONTROLLER;
key CONTROLLED;
integer menu_channel;
integer menu_handle;
integer playsounds = TRUE;
integer no_waits_yet;
integer verbose = 1;
Out(integer level, string out)
{
if (verbose >= level)
{
llOwnerSay(llGetScriptName() + "[" + version + "] " + out);
}
}
string strReplace(string str, string search, string replace)
{
return llDumpList2String(llParseStringKeepNulls(str, [search], []), replace);
}
DEBUGSay(integer level, string out)
{
if (DEBUG >= level)
{
llWhisper(0, out);
}
}
run_sequence()
{
while (SEQUENCE_POINTER >= 0)
{
string command = llList2String(CURRENT_SEQUENCE_ACTIONS, SEQUENCE_POINTER);
string data = llList2String(CURRENT_SEQUENCE_DATAS, SEQUENCE_POINTER);
list data_list = llParseStringKeepNulls(data, ["|"], []);
if (command == "PLAY")
{
DEBUGSay(2, "Playing pose " + data);
llMessageLinked(LINK_THIS, 90003, data, "");
llSleep(0.5);
}
else if (command == "SAY")
{
llSay(0, parse_text(data));
}
else if (command == "WHISPER")
{
llWhisper(0, parse_text(data));
}
else if (command == "SOUND")
{
if (playsounds)
{
string sound = llList2String(data_list, 0);
float volume = (float)llList2String(data_list, 1);
llPlaySound(sound, volume);
DEBUGSay(2, "Playing sound " + sound + " at volume " + (string)volume);
}
}
else if (command == "LOOP")
{
no_waits_yet = FALSE;
if (SEQUENCE_POINTER == llGetListLength(CURRENT_SEQUENCE_ACTIONS) - 1)
{
SEQUENCE_POINTER = -1;
DEBUGSay(2, "Looping back to start of sequence");
if (sequence_running)
{
llSetTimerEvent(0.1);
}
return;
}
}
else if (command == "WAIT")
{
if (sequence_running)
{
float time = (float)data;
DEBUGSay(2, "Waiting for " + (string)time + " seconds");
llSetTimerEvent(time);
if (time >= 2)
{
integer found;
integer next_POINTER = SEQUENCE_POINTER;
while (next_POINTER++ < llGetListLength(CURRENT_SEQUENCE_ACTIONS) && found == FALSE)
{
string next_command = llList2String(CURRENT_SEQUENCE_ACTIONS, SEQUENCE_POINTER + 1);
if (next_command == "WAIT" || next_command == "SOUND")
{
found = TRUE;
if (next_command == "SOUND")
{
list next_data_list = llParseStringKeepNulls(llList2String(CURRENT_SEQUENCE_DATAS, next_POINTER), ["|"], []);
string sound = llList2String(next_data_list, 0);
DEBUGSay(2, "Preloading sound " + sound);
llPreloadSound(sound);
}
}
}
}
no_waits_yet = FALSE;
}
return;
}
if (++SEQUENCE_POINTER >= llGetListLength(CURRENT_SEQUENCE_ACTIONS))
{
integer index = llListFindList(CURRENT_SEQUENCE_ACTIONS, ["LOOP"]);
if (index != -1)
{
SEQUENCE_POINTER = index;
DEBUGSay(2, "Looping back to line " + (string)SEQUENCE_POINTER + " of sequence");
if (sequence_running)
{
llSetTimerEvent(0.1);
}
return;
}
else
{
stop_sequence(FALSE);
return;
}
}
}
}
integer get_number_of_scripts()
{
integer i;
while (llGetInventoryType(main_script + " " + (string)(++i)) == INVENTORY_SCRIPT)
;
return i;
}
string parse_text(string say)
{
integer i;
for (i = 0; i < llGetListLength(SITTERS); i++)
{
string sitter_name = llList2String(llParseString2List(llKey2Name(llList2String(SITTERS, i)), [" "], []), 0);
if (sitter_name == "")
{
sitter_name = "nobody";
}
say = strReplace(say, "/" + (string)i, sitter_name);
}
return say;
}
start_sequence(integer index)
{
no_waits_yet = sequence_running = TRUE;
SEQUENCE_POINTER = 0;
CURRENT_SEQUENCE_NAME = llList2String(SEQUENCE_DATA_NAMES, index);
CURRENT_SEQUENCE_ACTIONS = llParseStringKeepNulls(llList2String(SEQUENCE_DATA_ACTIONS, index), ["◆"], []);
CURRENT_SEQUENCE_DATAS = llParseStringKeepNulls(llList2String(SEQUENCE_DATA_DATAS, index), ["◆"], []);
DEBUGSay(1, "Sequence '" + CURRENT_SEQUENCE_NAME + "' Started!");
}
stop_sequence(integer stopSound)
{
if (sequence_running)
{
DEBUGSay(1, "Sequence '" + CURRENT_SEQUENCE_NAME + "' Ended!");
}
sequence_running = FALSE;
SEQUENCE_POINTER = -1;
llSetTimerEvent(0);
if (stopSound && llListFindList(CURRENT_SEQUENCE_ACTIONS, ["SOUND"]) != -1)
{
llStopSound();
}
}
sequence_control()
{
llListenRemove(menu_handle);
menu_channel = ((integer)llFrand(0x7FFFFF80) + 1) * -1; // 7FFFFF80 = max float < 2^31
string pauseplay = "▶";
if (sequence_running)
{
pauseplay = "▮▮";
}
list menu_items = ["◀◀", pauseplay, "▶▶"];
menu_handle = llListen(menu_channel, "", CONTROLLER, "");
llDialog(CONTROLLER, product + " " + version + "\n\n[" + CURRENT_SEQUENCE_NAME + "]\n◀◀ = previous anim in sequence.\n▮▮ = pause sequence.\n▶▶ = skip to next anim in sequence.", order_buttons(["[BACK]"] + menu_items), menu_channel);
}
list order_buttons(list buttons)
{
return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}
commit_sequence_data()
{
SEQUENCE_DATA_NAMES += CURRENT_SEQUENCE_NAME;
SEQUENCE_DATA_ACTIONS += llDumpList2String(CURRENT_SEQUENCE_ACTIONS, "◆");
SEQUENCE_DATA_DATAS += llDumpList2String(CURRENT_SEQUENCE_DATAS, "◆");
}
default
{
state_entry()
{
notecard_key = llGetInventoryKey(notecard_name);
if (llGetInventoryType(notecard_name) == INVENTORY_NOTECARD)
{
Out(0, "Loading...");
notecard_query = llGetNotecardLine(notecard_name, notecard_line);
}
}
changed(integer change)
{
if (change & CHANGED_INVENTORY)
{
if (llGetInventoryKey(notecard_name) != notecard_key)
{
llResetScript();
}
}
}
dataserver(key query_id, string data)
{
if (query_id == notecard_query)
{
if (data == EOF)
{
commit_sequence_data();
state running;
}
else
{
list datalist = llParseString2List(data, [" "], []);
string command = llList2String(datalist, 0);
data = llStringTrim(llDumpList2String(llList2List(datalist, 1, 99999), " "), STRING_TRIM);
list commands = ["PLAY", "WAIT", "SAY", "WHISPER", "SOUND", "LOOP"];
if (command == "DEBUG")
{
DEBUG = (integer)data;
}
else if (command == "SEQUENCE")
{
if (CURRENT_SEQUENCE_NAME != "")
{
commit_sequence_data();
}
CURRENT_SEQUENCE_NAME = data;
CURRENT_SEQUENCE_ACTIONS = [];
CURRENT_SEQUENCE_DATAS = [];
}
else if (llListFindList(commands, [command]) != -1)
{
CURRENT_SEQUENCE_ACTIONS += command;
CURRENT_SEQUENCE_DATAS += data;
}
notecard_query = llGetNotecardLine(notecard_name, ++notecard_line);
}
}
}
}
state running
{
state_entry()
{
Out(0, (string)llGetListLength(SEQUENCE_DATA_NAMES) + " Sequences Ready, Mem=" + (string)(65536 - llGetUsedMemory()));
integer i;
for (i = 0; i < get_number_of_scripts(); i++)
{
SITTERS += NULL_KEY;
}
}
link_message(integer sender, integer num, string msg, key id)
{
if (sender == llGetLinkNumber())
{
if (num == 90065)
{
integer index = llListFindList(SITTERS, [id]);
if (index != -1)
{
SITTERS = llListReplaceList(SITTERS, [NULL_KEY], index, index);
}
stop_sequence(TRUE);
}
else if (num == 90030)
{
SITTERS = llListReplaceList(SITTERS, [NULL_KEY], (integer)msg, (integer)msg);
SITTERS = llListReplaceList(SITTERS, [NULL_KEY], (integer)((string)id), (integer)((string)id));
stop_sequence(TRUE);
}
else if (num == 90070)
{
SITTERS = llListReplaceList(SITTERS, [id], (integer)msg, (integer)msg);
}
else if (num == 90000)
{
stop_sequence(TRUE);
integer index = llListFindList(SEQUENCE_DATA_NAMES, [msg]);
if (index != -1)
{
start_sequence(index);
run_sequence();
}
}
else if (num == 90205)
{
llMessageLinked(LINK_SET, 90005, "", id);
playsounds = !playsounds;
if (playsounds)
{
llSay(0, "Sounds ON");
}
else
{
llSay(0, "Sounds OFF");
llStopSound();
}
}
else if (num == SEQUENCE_LINKNUMBER)
{
stop_sequence(TRUE);
list data = llParseStringKeepNulls(id, ["|"], []);
CONTROLLER = (key)llList2String(data, 0);
CONTROLLED = (key)llList2String(data, -1);
integer index = llListFindList(SEQUENCE_DATA_NAMES, [msg]);
if (index != -1)
{
start_sequence(index);
if (llListFindList(CURRENT_SEQUENCE_ACTIONS, ["WAIT"]) != -1 && llListFindList(CURRENT_SEQUENCE_ACTIONS, ["PLAY"]) != -1)
{
sequence_control();
}
else
{
llMessageLinked(LINK_SET, 90005, "", id);
}
run_sequence();
}
}
}
}
listen(integer listen_channel, string name, key id, string msg)
{
if (msg == "▮▮")
{
sequence_running = FALSE;
llSetTimerEvent(0);
DEBUGSay(1, "Sequence '" + CURRENT_SEQUENCE_NAME + "' Paused!");
}
else if (msg == "▶")
{
sequence_running = TRUE;
SEQUENCE_POINTER++;
DEBUGSay(1, "Sequence '" + CURRENT_SEQUENCE_NAME + "' Resumed!");
run_sequence();
}
else if (msg == "▶▶")
{
SEQUENCE_POINTER++;
run_sequence();
}
else if (msg == "◀◀")
{
integer count_waits;
while (SEQUENCE_POINTER > -1 && count_waits < 2)
{
SEQUENCE_POINTER--;
if (llList2String(CURRENT_SEQUENCE_ACTIONS, SEQUENCE_POINTER) == "WAIT")
{
count_waits++;
}
}
SEQUENCE_POINTER++;
run_sequence();
}
else if (msg == "[BACK]")
{
llMessageLinked(LINK_SET, 90005, "", (string)id + "|" + (string)CONTROLLED);
return;
}
sequence_control();
}
timer()
{
llSetTimerEvent(0);
SEQUENCE_POINTER++;
run_sequence();
}
on_rez(integer start)
{
playsounds = TRUE;
}
changed(integer change)
{
/*
if (change & CHANGED_LINK)
{
}
*/
if (change & CHANGED_INVENTORY)
{
if (llGetInventoryKey(notecard_name) != notecard_key || get_number_of_scripts() != llGetListLength(SITTERS))
{
llResetScript();
}
}
}
}