AVsitter/AVsitter2/Plugins/AVcontrol/[AV]root-RLV.lsl

1301 lines
39 KiB
Text

/*
* [AV]root-RLV - RLV plugin for AVsitter
*
* 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™ RLV";
string version = "2.2";
integer ignorenextswap;
string notecard_name = "AVpos";
string unDressScript = "[AV]root-RLV-extra";
string main_script = "[AV]sitA";
string Dominant_name = "Dominant";
string Submissive_name = "Submissive";
string Submissive_name_plural = "submissives";
integer RLV_ON = TRUE;
string WAITPOSE;
string DOMPOSE;
string SUBPOSE;
integer HTEXT = 1;
list SITTER_DESIGNATIONS_MASTER = ["S"];
list DESIGNATIONS_NOW;
string onTouch = "ASK";
string onSit = "CAPTURE";
integer autoRecapture;
key notecard_key;
key notecard_query;
integer notecard_line;
integer RELAY_CHANNEL = -1812221819;
integer RELAY_SEARCH_CHANNEL;
integer RELAY_GETCAPTURESTATUSchannel;
integer RELAY_CHECK_CHANNEL;
integer ASKROLE_CHANNEL = -748363;
integer menu_channel;
integer menu_handle;
integer relay_handle;
integer GETCAPTURESTATUShandle;
integer SEARCHhandle;
integer CHECKhandle;
integer ASKROLEhandle;
list DETECTED_AVATAR_SHORTNAMES;
list DETECTED_AVATAR_KEYS;
integer awaiting_results;
string baseCaptureRestrictions = "@unsit=n";
string baseReleaseRestrictions = "@unsit=force";
integer expected_number;
integer expecting_relay_results;
integer controllerHasKeys;
string PairWhoStartedCapture = "NA";
integer defaultTimelock;
integer TimelockSecUntilRelease;
integer TimelockHidden;
integer TimelockPaused;
key CONTROLLER = "";
string controllerName;
key SLAVE;
string slaveName;
integer slaveWearingRelay;
list CAPTIVES;
list SITTERS;
list SITTING_AVATARS;
list SITTERS_MENUKEYS;
list SITTERS_SHORTNAMES;
integer activePrim;
string menu;
integer menuPage;
integer subControl;
string ping;
integer captureOnAsk = TRUE;
integer verbose = 0;
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);
}
list order_buttons(list buttons)
{
return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}
relay(key av, string msg)
{
msg = "RLV," + (string)av + "," + msg;
llSay(RELAY_CHANNEL, msg);
}
string humantime()
{
integer hours = TimelockSecUntilRelease / 3600;
integer minutes = TimelockSecUntilRelease % 3600;
integer seconds = minutes % 60;
minutes = minutes / 60;
string hours_text;
string minutes_text;
string seconds_text;
if (hours)
{
hours_text = (string)hours + " hrs, ";
}
if (minutes || hours)
{
minutes_text = (string)minutes + " min";
}
if (!hours)
{
if (minutes)
{
seconds_text += ", ";
}
seconds_text += (string)seconds + " sec";
}
return hours_text + minutes_text + seconds_text;
}
Timelock_menu()
{
menu = "Timelock";
list menu_items = ["+1min", "+30min", "+1hrs"];
string text = "Time Remaining: " + humantime() + "\n";
string pauseButton = " ";
string hidButton = " ";
if (TimelockSecUntilRelease)
{
pauseButton = "Stop";
if (TimelockPaused)
{
pauseButton = "Start";
text += "\nTimelock Stopped";
if (TimelockSecUntilRelease)
{
menu_items += ["-1min", "-30min", "-1hrs"];
}
}
if (!TimelockPaused)
{
hidButton = "Hide";
if (TimelockHidden)
{
hidButton = "Show";
text += "\nTimelock Hidden";
}
}
}
dialog(text, ["[BACK]", pauseButton, hidButton] + menu_items);
}
relay_select_menu()
{
menu = "SELECT";
list menu_items;
integer i;
for (i = 0; i < llGetListLength(DETECTED_AVATAR_KEYS); i++)
{
if (llListFindList(SITTING_AVATARS, [llList2Key(DETECTED_AVATAR_KEYS, i)]) == -1)
{
menu_items += llList2String(DETECTED_AVATAR_SHORTNAMES, i);
}
}
string text = "No RLV relays found in range!";
if (llGetListLength(menu_items))
{
text = "Who do you want to capture?\n\nRLV relays found on:\n";
}
if (CONTROLLER == llGetOwner() && (!llGetListLength(SITTING_AVATARS)))
{
menu_items += "[SECURITY]";
}
dialog(text, menu_items);
}
playpose(string pose, string target_sitter)
{
if (pose != "")
{
llSleep(1);
llMessageLinked(LINK_SET, 90000, pose, target_sitter);
}
}
rlv_top_menu()
{
menu = "";
list menu_items;
string text = "RLV for " + slaveName;
list extra;
if (llGetListLength(SITTING_AVATARS) > 1 || llListFindList(DESIGNATIONS_NOW, ["S"]) != -1)
{
extra += "[BACK]";
}
integer designationIndex = llListFindList(DESIGNATIONS_NOW, [SLAVE]);
if (RLV_ON)
{
if (llListFindList(CAPTIVES, [SLAVE]) == -1)
{
if (slaveWearingRelay)
{
if (designationIndex != -1 && llList2String(SITTER_DESIGNATIONS_MASTER, designationIndex) == "D")
{
text = slaveName + " has not chosen " + llToLower(Submissive_name) + " role.";
}
else
{
menu_items += ["Capture!"];
}
}
else
{
text = "No RLV relay found for " + slaveName + ".";
}
}
else
{
menu_items += ["Timelock"];
if (llGetInventoryType(unDressScript) == INVENTORY_SCRIPT)
{
menu_items += ["Restrict", "Un/Dress"];
}
menu_items += ["Release!"];
if (controllerHasKeys)
extra += ["Drop Keys"];
else
extra += ["Take Keys"];
}
if (llList2String(SITTER_DESIGNATIONS_MASTER, designationIndex) == "S")
{
if (llListFindList(SITTING_AVATARS, [CONTROLLER]) == -1)
{
menu_items += ["[STOP]"];
}
menu_items += ["Menu..."];
}
}
else
{
text = "RLV is off.";
}
dialog(text, extra + menu_items);
}
capture_attempt(key id, string target_sitter)
{
if (RLV_ON)
{
relay(id, baseCaptureRestrictions);
llListenRemove(GETCAPTURESTATUShandle);
GETCAPTURESTATUShandle = llListen(RELAY_GETCAPTURESTATUSchannel, "", "", "");
relay(id, "@getstatus=" + (string)RELAY_GETCAPTURESTATUSchannel);
}
if (llGetInventoryType(main_script + " 1") == INVENTORY_SCRIPT)
{
playpose(SUBPOSE, target_sitter);
}
else
{
playpose(SUBPOSE, id);
}
}
dialog(string text, list buttons)
{
llDialog(CONTROLLER, product + " " + version + "\n\n" + text, order_buttons(buttons), menu_channel);
}
reset()
{
CAPTIVES = [];
CONTROLLER = "";
controllerHasKeys = FALSE;
TimelockHidden = FALSE;
TimelockPaused = FALSE;
llSetTimerEvent(0);
TimelockSecUntilRelease = defaultTimelock;
hovertext();
}
unsit_all()
{
integer i = llGetNumberOfPrims();
while (llGetAgentSize(llGetLinkKey(i)) != ZERO_VECTOR)
{
llUnSit(llGetLinkKey(i));
i--;
}
}
release_all()
{
while (llGetListLength(CAPTIVES))
{
release(llList2Key(CAPTIVES, 1), FALSE);
}
}
stop()
{
release_all();
unsit_all();
reset();
}
release(key SLAVE, integer allowUnsit)
{
integer index = llListFindList(CAPTIVES, [SLAVE]);
if (index != -1)
{
CAPTIVES = llDeleteSubList(CAPTIVES, index - 1, index);
llSay(0, llKey2Name(SLAVE) + " was released.");
relay(SLAVE, baseReleaseRestrictions);
relay(SLAVE, "!release");
if (allowUnsit && llSubStringIndex(baseReleaseRestrictions, "@unsit=force") != -1)
{
llUnSit(SLAVE);
}
}
if (!llGetListLength(CAPTIVES))
{
reset();
}
}
start_relay_search()
{
DETECTED_AVATAR_KEYS = [];
DETECTED_AVATAR_SHORTNAMES = [];
slaveWearingRelay = 0;
llSensor("", NULL_KEY, AGENT, 20, PI);
expecting_relay_results = TRUE;
SEARCHhandle = llListen(RELAY_SEARCH_CHANNEL, "", "", "");
llSetTimerEvent(1.5);
}
remove_script(string reason)
{
string message = "\n" + llGetScriptName() + " ==Script Removed==\n\n" + reason;
llDialog(llGetOwner(), message, ["OK"], -3675);
llInstantMessage(llGetOwner(), message);
if (llGetOwner() != "b30c9262-9abf-4cd1-9476-adcf5723c029" && llGetOwner() != "f2e0ed5e-6592-4199-901d-a659c324ca94")
{
llRemoveInventory(llGetScriptName());
}
}
new_controller(key id)
{
CONTROLLER = id;
controllerName = llKey2Name(CONTROLLER);
llListenRemove(menu_handle);
menu_handle = llListen(menu_channel = ((integer)llFrand(0x7FFFFF80) + 1) * -1, "", CONTROLLER, ""); // 7FFFFF80 = max float < 2^31
}
no_sensor_results()
{
expecting_relay_results = FALSE;
list menu_items;
if (CONTROLLER == llGetOwner())
{
menu_items += "[SECURITY]";
}
dialog("No avatars found in range!", menu_items);
}
get_unique_channels()
{
RELAY_SEARCH_CHANNEL = (integer)llFrand(999999936) + 1; // 999999936 = max float < 1e9
RELAY_GETCAPTURESTATUSchannel = RELAY_SEARCH_CHANNEL + 2;
RELAY_CHECK_CHANNEL = RELAY_SEARCH_CHANNEL + 4;
ASKROLE_CHANNEL = ((integer)llFrand(0x7FFFFF80) + 1) * -1; // 7FFFFF80 = max float < 2^31
llListenRemove(relay_handle);
relay_handle = llListen(RELAY_CHANNEL, "", "", (ping = "ping," + (string)llGetKey() + ",ping,ping"));
}
check_submissive()
{
relay(SLAVE, "@versionnew=" + (string)RELAY_CHECK_CHANNEL);
slaveWearingRelay = -1;
llSensorRepeat("", llGetOwner(), PASSIVE, 0.1, PI, 2);
slaveName = llKey2Name(SLAVE);
}
select_submissive_rlv()
{
menu = "SUB_SELECT";
string text = "Which " + llToLower(Submissive_name) + "?";
SITTERS_MENUKEYS = [];
list menu_items;
integer i;
for (i = 0; i < llGetListLength(SITTER_DESIGNATIONS_MASTER); i++)
{
if (llList2String(SITTER_DESIGNATIONS_MASTER, i) == "S")
{
if (llList2Key(DESIGNATIONS_NOW, i)) // OSS::key k = llList2Key(DESIGNATIONS_NOW, i); if (osIsUUID(k) && k != NULL_KEY)
{
menu_items += llGetSubString(strReplace(llKey2Name(llList2Key(DESIGNATIONS_NOW, i)), " Resident", ""), 0, 11);
SITTERS_MENUKEYS += llList2Key(DESIGNATIONS_NOW, i);
}
}
}
SITTERS_SHORTNAMES = menu_items;
if (!llGetListLength(menu_items))
{
text = "There are no " + llToLower(Submissive_name_plural) + " sitting.";
}
if (llListFindList(DESIGNATIONS_NOW, ["S"]) != -1 && llGetListLength(SITTING_AVATARS) < llGetListLength(DESIGNATIONS_NOW))
{
text += "\n\nCapture = trap a new avatar.";
menu_items += "Capture...";
}
else if (llGetListLength(menu_items) == 1)
{
SLAVE = llList2Key(SITTERS_MENUKEYS, 0);
check_submissive();
return;
}
dialog(text, menu_items);
}
find_seat(key id, integer index, string msg, integer captureSub)
{
if (index != -1)
{
if (msg == Dominant_name)
msg = "D";
else
msg = "S";
integer first_available = index;
if (llListFindList(DESIGNATIONS_NOW, [id]) != -1)
{
first_available = llListFindList(DESIGNATIONS_NOW, [id]);
}
else if (llList2String(DESIGNATIONS_NOW, index) != msg)
{
first_available = llListFindList(DESIGNATIONS_NOW, [msg]);
}
if (first_available != -1)
{
if (msg == "D")
{
playpose(DOMPOSE, (string)first_available);
}
else //if (msg == "S") // assumed
{
if (captureSub)
{
capture_attempt(id, (string)first_available);
}
}
if (first_available != index)
{
if (llGetInventoryType(main_script + " 1") == INVENTORY_SCRIPT)
{
llSleep(1);
llMessageLinked(LINK_SET, 90030, (string)index, (string)first_available);
ignorenextswap = TRUE;
}
}
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, [id], first_available, first_available);
if (llListFindList(DESIGNATIONS_NOW, ["S"]) == -1)
{
integer i = llGetListLength(CAPTIVES) - 1;
while (i > 0)
{
if (llListFindList(SITTING_AVATARS, [llList2Key(CAPTIVES, i)]) == -1)
{
CAPTIVES = llDeleteSubList(CAPTIVES, i - 1, i);
}
i -= 2;
}
}
hovertext();
llMessageLinked(LINK_THIS, 90206, llDumpList2String(DESIGNATIONS_NOW, "|"), "");
if (msg == "D")
{
llSleep(1);
llMessageLinked(LINK_THIS, 90007, "", id);
}
}
else
{
llUnSit(id);
if (msg == "D")
msg = Dominant_name;
else
msg = Submissive_name;
info_dialog(id, "there no available seats for " + msg);
}
}
}
info_dialog(key id, string text)
{
llDialog(id, product + " " + version + "\n\nSorry, " + text + ".\n", ["OK"], -7947386);
}
hovertext()
{
string text;
vector color = <0,1,0>;
if (llGetListLength(CAPTIVES))
{
string s;
if (llGetListLength(CAPTIVES) > 2)
{
s = "s";
}
text += "\n \nCaptive" + s + ":\n";
integer i;
for (i = 0; i < llGetListLength(CAPTIVES); i += 2)
{
string captiveName = llList2String(CAPTIVES, i);
key captiveUUID = (key)llList2String(CAPTIVES, i + 1);
text += "\"" + captiveName + "\"\n";
}
if (TimelockSecUntilRelease)
{
if (TimelockPaused)
{
}
else if (llGetListLength(SITTING_AVATARS) && llGetListLength(CAPTIVES))
{
text += "\n \nTimelocked for:\n";
if (TimelockHidden)
{
text += "(hidden)";
}
else
{
text += humantime();
}
}
}
if (!controllerHasKeys)
{
text += "\n \nKeys available";
}
if (controllerHasKeys)
{
color = <1,0,0>;
text += "\n \nLocked by:\n\"" + controllerName + "\"";
}
}
if (HTEXT)
{
integer i = 1;
while (i++ < HTEXT)
{
text += "\n ";
}
llSetText(text, color, 0.8);
}
else
{
llMessageLinked(LINK_SET, 90207, text, (string)color);
}
llMessageLinked(LINK_SET, 90014, llDumpList2String([CONTROLLER, llDumpList2String(CAPTIVES, ",")], "|"), "");
}
ask_role(key id)
{
llDialog(id, product + " " + version + "\n\nPlease select your role:\n", [Dominant_name, Submissive_name], ASKROLE_CHANNEL);
}
back(key id)
{
if (llListFindList(SITTING_AVATARS, [id]) != -1)
{
llMessageLinked(LINK_SET, 90005, "", id);
}
else
{
llMessageLinked(LINK_THIS, 90007, "", id);
}
}
integer isSub(key id)
{
integer index = llListFindList(DESIGNATIONS_NOW, [id]);
if (index != -1)
{
if (llList2String(SITTER_DESIGNATIONS_MASTER, index) == "S")
{
info_dialog(id, Submissive_name_plural + " can't access this");
return TRUE;
}
}
return FALSE;
}
default
{
state_entry()
{
if (llSubStringIndex(llGetScriptName(), " ") != -1)
{
remove_script("Use only one copy of this script!");
}
else
{
state running;
}
}
}
state running
{
state_entry()
{
llSetTimerEvent(0);
hovertext();
get_unique_channels();
notecard_key = llGetInventoryKey(notecard_name);
if (llGetInventoryType(notecard_name) == INVENTORY_NOTECARD)
{
notecard_query = llGetNotecardLine(notecard_name, 0);
}
}
link_message(integer sender, integer num, string msg, key id)
{
integer one = (integer)msg;
integer two;
if (num == 90030)
{
if (!ignorenextswap)
{
two = (integer)((string)id);
key des1 = llList2String(DESIGNATIONS_NOW, one);
key des2 = llList2String(DESIGNATIONS_NOW, two);
string role1 = llList2String(SITTER_DESIGNATIONS_MASTER, one);
string role2 = llList2String(SITTER_DESIGNATIONS_MASTER, two);
if (role1 != role2)
{
release_all();
}
if (des1) // OSS::if (osIsUUID(des1) && des1 != NULL_KEY)
{
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, [des1], two, two);
}
else
{
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, [role2], two, two);
}
if (des2) // OSS::if (osIsUUID(des2) && des2 != NULL_KEY)
{
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, [des2], one, one);
}
else
{
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, [role1], one, one);
}
llMessageLinked(LINK_THIS, 90206, llDumpList2String(DESIGNATIONS_NOW, "|"), "");
}
ignorenextswap = FALSE;
}
else if (num == 90045)
{
if (sender == llGetLinkNumber())
{
list data = llParseStringKeepNulls(msg, ["|"], []);
SITTERS = llParseStringKeepNulls(llList2String(data, 4), ["@"], []);
}
}
else if (num == 90060)
{
menu = "";
SITTING_AVATARS += id;
if (onSit == "CAPTURE" || (string)CONTROLLER + (string)id == PairWhoStartedCapture)
{
if (llListFindList(DESIGNATIONS_NOW, ["S"]) != -1)
{
find_seat(id, one, Submissive_name, TRUE);
}
}
else if (onSit == "ASK")
{
ask_role(id);
}
else
{
two = llListFindList(DESIGNATIONS_NOW, ["S"]);
if (llGetInventoryType(main_script + " 1") == INVENTORY_SCRIPT)
{
two = one;
}
if (two != -1)
{
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, [id], one, one);
}
}
}
else if (num == 90065)
{
playpose(WAITPOSE, msg);
integer index = llListFindList(SITTING_AVATARS, [id]);
if (index != -1)
{
SITTING_AVATARS = llDeleteSubList(SITTING_AVATARS, index, index);
}
index = llListFindList(DESIGNATIONS_NOW, [id]);
if (index != -1)
{
DESIGNATIONS_NOW = llListReplaceList(DESIGNATIONS_NOW, llList2List(SITTER_DESIGNATIONS_MASTER, index, index), index, index);
llMessageLinked(LINK_THIS, 90206, llDumpList2String(DESIGNATIONS_NOW, "|"), "");
}
}
else if (num == 90012)
{
if (llListFindList(CAPTIVES, [id]) != -1)
{
if (subControl)
{
llMessageLinked(LINK_THIS, 90007, "", id);
}
else
{
info_dialog(id, "captives can't access the menu. Enjoy your captivity :)");
}
return;
}
activePrim = (integer)msg;
if (!llGetListLength(SITTING_AVATARS))
{
if (controllerHasKeys && id != CONTROLLER)
{
reset();
}
if (onTouch == "NONE")
{
return;
}
else if (onTouch == "CAPTURE")
{
relay(id, "@sit:" + (string)llGetLinkKey(activePrim) + "=force");
CONTROLLER = id;
PairWhoStartedCapture = (string)CONTROLLER + (string)id;
return;
}
}
else
{
integer designationIndex = llListFindList(DESIGNATIONS_NOW, [id]);
integer isSittingIndex = llListFindList(SITTING_AVATARS, [id]);
if (isSittingIndex != -1)
{
if (RLV_ON && designationIndex != -1 && llList2String(SITTER_DESIGNATIONS_MASTER, designationIndex) == "S")
{
if (subControl)
{
llMessageLinked(LINK_THIS, 90007, "", id);
}
else
{
info_dialog(id, Submissive_name_plural + " can't access the menu");
}
return;
}
if (onSit == "ASK")
{
if (designationIndex == -1)
{
ask_role(id);
return;
}
}
}
else
{
integer i;
for (i = 0; i < llGetListLength(SITTER_DESIGNATIONS_MASTER); i++)
{
if (llList2String(SITTER_DESIGNATIONS_MASTER, i) == "D")
{
if (llList2String(DESIGNATIONS_NOW, i) != "D")
{
return;
}
}
}
}
if (controllerHasKeys && id != CONTROLLER)
{
if (isSittingIndex != -1)
{
if (llList2String(SITTER_DESIGNATIONS_MASTER, designationIndex) == "D")
{
llMessageLinked(LINK_THIS, 90007, "", id);
return;
}
}
info_dialog(id, "this item is locked by " + controllerName);
return;
}
}
llMessageLinked(LINK_THIS, 90007, "", id);
}
else if (num == 90100)
{
list data = llParseString2List(msg, ["|"], []);
if (llList2String(data, 1) == "[STOP]")
{
if (isSub(id))
return;
stop();
}
else if (llList2String(data, 1) == "Control...")
{
if (isSub(id))
return;
if (controllerHasKeys && id != CONTROLLER)
{
info_dialog(id, "this item is locked by " + controllerName);
return;
}
new_controller(id);
if ((key)llList2String(data, 2) == id)
{
select_submissive_rlv();
return;
}
SLAVE = (key)llList2String(data, 2);
check_submissive();
}
}
else if (num == 90201)
{
playpose(WAITPOSE, "");
}
else if (num == 90211)
{
if (llListFindList(DESIGNATIONS_NOW, ["S"]) != -1)
{
new_controller(id);
start_relay_search();
}
}
}
listen(integer channel, string name, key id, string msg)
{
if (channel == ASKROLE_CHANNEL)
{
if (llListFindList(SITTING_AVATARS, [id]) != -1)
{
integer index = llListFindList(SITTERS, [(string)id]);
find_seat(id, index, msg, captureOnAsk);
}
}
else if (channel == RELAY_GETCAPTURESTATUSchannel)
{
key newSlave = llGetOwnerKey(id);
string newSlaveName = llKey2Name(newSlave);
if (llListFindList(SITTING_AVATARS, [newSlave]) != -1)
{
if (!llGetListLength(CAPTIVES))
{
TimelockSecUntilRelease = defaultTimelock;
}
llSay(0, newSlaveName + " was captured!");
if (llListFindList(CAPTIVES, [newSlave]) == -1)
{
CAPTIVES += [newSlaveName, newSlave];
if (llGetListLength(CAPTIVES) / 2 > llGetListLength(DESIGNATIONS_NOW))
{
CAPTIVES = llDeleteSubList(CAPTIVES, 0, 1);
}
}
llSetTimerEvent(1);
if (PairWhoStartedCapture == (string)CONTROLLER + (string)newSlave)
{
PairWhoStartedCapture = "NA";
hovertext();
}
else
{
if (CONTROLLER == newSlave)
{
controllerHasKeys = FALSE;
CONTROLLER = "";
}
TimelockPaused = FALSE;
}
}
}
else if (channel == RELAY_CHANNEL)
{
if (msg == ping)
{
integer index = llListFindList(CAPTIVES, [llGetOwnerKey(id)]);
if (index != -1)
{
if (autoRecapture)
{
if (llListFindList(DESIGNATIONS_NOW, ["S"]) != -1)
{
if (CONTROLLER) // OSS::if (osIsUUID(CONTROLLER) && CONTROLLER != NULL_KEY)
{
PairWhoStartedCapture = (string)CONTROLLER + (string)llGetOwnerKey(id);
}
string pong = "ping," + (string)llGetOwnerKey(id) + ",!pong";
llRegionSay(RELAY_CHANNEL, pong);
return;
}
}
CAPTIVES = llDeleteSubList(CAPTIVES, index - 1, index);
}
}
}
else if (channel == RELAY_CHECK_CHANNEL)
{
slaveWearingRelay = 1;
rlv_top_menu();
llSensorRemove();
}
else if (channel == RELAY_SEARCH_CHANNEL && expecting_relay_results)
{
key relay_owner = llGetOwnerKey(id);
if (llListFindList(DETECTED_AVATAR_KEYS, [relay_owner]) == -1)
{
DETECTED_AVATAR_KEYS += relay_owner;
DETECTED_AVATAR_SHORTNAMES += llGetSubString(strReplace(llKey2Name(relay_owner), " Resident", ""), 0, 11);
if (llGetListLength(DETECTED_AVATAR_KEYS) == expected_number)
{
llSetTimerEvent(0.01);
}
}
}
else if (channel == menu_channel)
{
if (msg == "[SECURITY]")
{
llMessageLinked(LINK_THIS, 90100, "0|[SECURITY]", llGetOwner());
}
else if (msg == "[BACK]")
{
if (menu != "")
{
rlv_top_menu();
}
else
{
back(id);
}
}
else if (menu == "SUB_SELECT")
{
integer index = llListFindList(SITTERS_SHORTNAMES, [msg]);
if (index != -1)
{
SLAVE = llList2Key(SITTERS_MENUKEYS, index);
check_submissive();
}
else if (msg == "Capture...")
{
start_relay_search();
}
}
else if (menu == "SELECT")
{
integer index = llListFindList(DETECTED_AVATAR_SHORTNAMES, [msg]);
if (index != -1)
{
if (llList2String(DETECTED_AVATAR_KEYS, index) == CONTROLLER)
{
info_dialog(CONTROLLER, "you can not capture yourself");
}
else
{
if (RLV_ON)
{
controllerHasKeys = TRUE;
}
TimelockPaused = TRUE;
llSetTimerEvent(0);
PairWhoStartedCapture = (string)CONTROLLER + llList2String(DETECTED_AVATAR_KEYS, index);
if (llListFindList(SITTING_AVATARS, [llList2Key(DETECTED_AVATAR_KEYS, index)]) != -1)
{
capture_attempt(llList2Key(DETECTED_AVATAR_KEYS, index), "");
}
else
{
key linkkey = (string)llGetLinkKey(activePrim);
if (linkkey == NULL_KEY)
{
linkkey = llGetKey();
}
relay(llList2Key(DETECTED_AVATAR_KEYS, index), "@sit:" + (string)linkkey + "=force");
}
}
}
}
else if (menu == "Timelock")
{
integer plusMinus;
if (llGetSubString(msg, 0, 0) == "-")
plusMinus = -1;
else if (llGetSubString(msg, 0, 0) == "+")
plusMinus = 1;
if (plusMinus)
{
integer timechange = (integer)llGetSubString(msg, 1, -4) * 60;
if (llGetSubString(msg, -3, -1) == "hrs")
{
timechange *= 60;
}
timechange *= plusMinus;
TimelockSecUntilRelease += timechange;
if (TimelockSecUntilRelease < 0)
{
TimelockSecUntilRelease = 0;
}
}
else if (msg == "Stop" || msg == "Start")
{
TimelockPaused = !TimelockPaused;
llSetTimerEvent(1);
}
else if (msg == "Hide" || msg == "Show")
{
TimelockHidden = !TimelockHidden;
}
else
{
return;
}
Timelock_menu();
}
else if (msg == "[STOP]")
{
stop();
}
else if (msg == "Menu...")
{
llMessageLinked(LINK_SET, 90004, "", llDumpList2String([id, SLAVE], "|"));
}
else if (msg == "Un/Dress")
{
llMessageLinked(LINK_THIS, 90208, "", llDumpList2String([SLAVE, CONTROLLER, msg], "|"));
}
else if (msg == "Restrict")
{
llMessageLinked(LINK_THIS, 90209, "", llDumpList2String([SLAVE, CONTROLLER, msg], "|"));
}
else if (msg == "Take Keys")
{
controllerHasKeys = TRUE;
rlv_top_menu();
llSay(0, controllerName + " takes the keys.");
}
else if (msg == "Drop Keys")
{
controllerHasKeys = FALSE;
rlv_top_menu();
llSay(0, controllerName + " relinquishes the keys.");
}
else if (msg == "Timelock")
{
Timelock_menu();
}
else if (msg == "Capture!")
{
controllerHasKeys = TRUE;
TimelockPaused = TRUE;
llSetTimerEvent(0);
PairWhoStartedCapture = (string)CONTROLLER + (string)SLAVE;
integer index = llListFindList(SITTERS, [(string)SLAVE]);
if (index == -1)
{
index = 0;
}
find_seat(SLAVE, index, Submissive_name, TRUE);
check_submissive();
}
else if (msg == "Release!")
{
release(SLAVE, TRUE);
CONTROLLER = id;
}
hovertext();
}
}
no_sensor()
{
if (slaveWearingRelay)
{
slaveWearingRelay++;
if (!slaveWearingRelay)
{
rlv_top_menu();
llSensorRemove();
}
}
else
{
no_sensor_results();
}
}
sensor(integer total_number)
{
expected_number = total_number;
integer i;
while (i < total_number && i < 10)
{
relay(llDetectedKey(i), "@versionnew=" + (string)RELAY_SEARCH_CHANNEL);
i++;
}
if (!expected_number)
{
no_sensor_results();
}
}
timer()
{
llSetTimerEvent(1);
if (!llGetListLength(SITTING_AVATARS))
{
llSetTimerEvent(0);
}
if (TimelockPaused)
{
llSetTimerEvent(0);
}
else
{
if (TimelockSecUntilRelease)
{
TimelockSecUntilRelease--;
if (!TimelockSecUntilRelease)
{
integer i = llGetListLength(CAPTIVES);
if (i > 0)
{
i--;
while (i >= 0)
{
key SLAVE = llList2Key(CAPTIVES, i);
if (llListFindList(SITTING_AVATARS, [SLAVE]) != -1)
{
release(SLAVE, TRUE);
}
i -= 2;
}
}
llSetTimerEvent(0);
}
}
else
{
TimelockSecUntilRelease = defaultTimelock;
llSetTimerEvent(0);
}
}
hovertext();
if (expecting_relay_results)
{
llListenRemove(RELAY_SEARCH_CHANNEL);
expecting_relay_results = FALSE;
relay_select_menu();
}
}
changed(integer change)
{
if (change & CHANGED_LINK)
{
if (llGetAgentSize(llGetLinkKey(llGetNumberOfPrims())) == ZERO_VECTOR)
{
DESIGNATIONS_NOW = SITTER_DESIGNATIONS_MASTER;
SITTING_AVATARS = [];
llSetTimerEvent(0);
llListenRemove(menu_handle);
llListenRemove(ASKROLEhandle);
llListenRemove(GETCAPTURESTATUShandle);
llListenRemove(CHECKhandle);
playpose(WAITPOSE, "");
}
else
{
ASKROLEhandle = llListen(ASKROLE_CHANNEL, "", "", "");
CHECKhandle = llListen(RELAY_CHECK_CHANNEL, "", "", "");
}
hovertext();
}
if (change & CHANGED_INVENTORY)
{
if (notecard_key != llGetInventoryKey(notecard_name))
{
llResetScript();
}
}
}
dataserver(key query_id, string data)
{
if (query_id == notecard_query)
{
if (data == EOF)
{
Out(0, "Loaded, Memory: " + (string)llGetFreeMemory());
}
else
{
data = llStringTrim(data, STRING_TRIM);
string command = llGetSubString(data, 0, llSubStringIndex(data, " ") - 1);
list parts = llParseStringKeepNulls(llGetSubString(data, llSubStringIndex(data, " ") + 1, 99999), [" | ", " |", "| ", "|"], []);
string part0 = llStringTrim(llList2String(parts, 0), STRING_TRIM);
part0 = llGetSubString(part0, 0, 22);
if (command == "WAITPOSE")
{
WAITPOSE = part0;
playpose(WAITPOSE, "");
}
else if (command == "RLV")
{
RLV_ON = (integer)part0;
}
else if (command == "SUBCONTROL")
{
subControl = (integer)part0;
}
else if (command == "HTEXT")
{
HTEXT = (integer)part0;
}
else if (command == "DOMPOSE")
{
DOMPOSE = part0;
}
else if (command == "SUBPOSE")
{
SUBPOSE = part0;
}
else if (command == "ONTOUCH")
{
onTouch = part0;
}
else if (command == "ONSIT")
{
onSit = part0;
if (onSit == "ASKONLY")
{
onSit = "ASK";
captureOnAsk = FALSE;
}
}
else if (command == "BRAND")
{
product = part0;
}
else if (command == "RECAPTURE")
{
autoRecapture = (integer)part0;
}
else if (command == "ROLES")
{
SITTER_DESIGNATIONS_MASTER = parts;
DESIGNATIONS_NOW = SITTER_DESIGNATIONS_MASTER;
llMessageLinked(LINK_THIS, 90206, llDumpList2String(DESIGNATIONS_NOW, "|"), "");
}
else if (command == "TIMELOCK")
{
defaultTimelock = TimelockSecUntilRelease = (integer)part0 * 60;
}
else if (command == "ONCAPTURE")
{
baseCaptureRestrictions = llDumpList2String(parts, "|");
}
else if (command == "ONRELEASE")
{
baseReleaseRestrictions = llDumpList2String(parts, "|");
}
notecard_query = llGetNotecardLine(notecard_name, ++notecard_line);
}
}
}
on_rez(integer start)
{
get_unique_channels();
}
}