first commit
This commit is contained in:
parent
e7d01132b3
commit
34f30ac80a
48 changed files with 13160 additions and 534 deletions
608
AVsitter2/Plugins/AVprop/[AV]menu.lsl
Normal file
608
AVsitter2/Plugins/AVprop/[AV]menu.lsl
Normal file
|
@ -0,0 +1,608 @@
|
|||
/*
|
||||
* 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 (c) 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 = "AVmenu™";
|
||||
string version = "2.2";
|
||||
integer verbose = 0;
|
||||
string prop_script = "[AV]prop";
|
||||
string notecard_name = "AVpos";
|
||||
string main_script = "[AV]sitA";
|
||||
string custom_text;
|
||||
list MENUCONTROL_TYPES = ["ALL", "OWNER ONLY", "GROUP ONLY"];
|
||||
integer MENUCONTROL_INDEX;
|
||||
integer owner_only;
|
||||
integer last_menu_unixtime;
|
||||
string last_menu_avatar;
|
||||
integer menu_channel;
|
||||
key notecard_key;
|
||||
key notecard_query;
|
||||
list MENU_LIST;
|
||||
list DATA_LIST;
|
||||
integer MTYPE;
|
||||
integer notecard_line;
|
||||
integer current_menu = -1;
|
||||
integer menu_page;
|
||||
integer choosing;
|
||||
string choice;
|
||||
integer listen_handle;
|
||||
integer number_per_page = 9;
|
||||
integer menu_pages;
|
||||
string last_text;
|
||||
integer pass_security(key id)
|
||||
{
|
||||
integer access_allowed = FALSE;
|
||||
string SECURITY_TYPE = llList2String(MENUCONTROL_TYPES, MENUCONTROL_INDEX);
|
||||
if (SECURITY_TYPE == "ALL")
|
||||
{
|
||||
access_allowed = TRUE;
|
||||
}
|
||||
else if (SECURITY_TYPE == "GROUP ONLY" && llSameGroup(id) == TRUE)
|
||||
{
|
||||
access_allowed = TRUE;
|
||||
}
|
||||
else if (id == llGetOwner())
|
||||
{
|
||||
access_allowed = TRUE;
|
||||
}
|
||||
return access_allowed;
|
||||
}
|
||||
check_avsit()
|
||||
{
|
||||
if (llGetInventoryType(main_script) == INVENTORY_SCRIPT)
|
||||
{
|
||||
remove_script("This script can not be used with the sit script in the same prim. Removing script!");
|
||||
}
|
||||
}
|
||||
list order_buttons(list buttons)
|
||||
{
|
||||
return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
|
||||
}
|
||||
Out(integer level, string out)
|
||||
{
|
||||
if (verbose >= level)
|
||||
{
|
||||
llOwnerSay(llGetScriptName() + "[" + version + "] " + out);
|
||||
}
|
||||
}
|
||||
Readout_Say(string say)
|
||||
{
|
||||
llSleep(0.2);
|
||||
string objectname = llGetObjectName();
|
||||
llSetObjectName("");
|
||||
llRegionSayTo(llGetOwner(), 0, "◆" + say);
|
||||
llSetObjectName(objectname);
|
||||
}
|
||||
dialog(key av, string menu_text, list menu_items)
|
||||
{
|
||||
llDialog(av, product + " " + version + "\n\n" + menu_text, order_buttons(menu_items), menu_channel);
|
||||
last_menu_unixtime = llGetUnixTime();
|
||||
llSetTimerEvent(120);
|
||||
}
|
||||
integer avprop_is_copy_transfer(integer owner_mask)
|
||||
{
|
||||
integer perms = llGetInventoryPermMask(prop_script, owner_mask);
|
||||
if (perms & PERM_COPY && perms & PERM_TRANSFER)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
integer prim_is_mod()
|
||||
{
|
||||
integer perms = llGetObjectPermMask(MASK_OWNER);
|
||||
if (perms & PERM_MODIFY)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
menu_check(string name, key id)
|
||||
{
|
||||
if (pass_security(id) == TRUE)
|
||||
{
|
||||
if (name == last_menu_avatar || llGetUnixTime() - last_menu_unixtime > 5)
|
||||
{
|
||||
last_menu_unixtime = llGetUnixTime();
|
||||
last_menu_avatar = name;
|
||||
menu_page = 0;
|
||||
current_menu = -1;
|
||||
prop_menu(FALSE, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
llDialog(id, product + " " + version + "\n\n" + llList2String(llParseString2List(last_menu_avatar, [" "], []), 0) + " is already using the menu.\nPlease wait a moment.", [], -585868);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llDialog(id, product + " " + version + "\n\n" + "Sorry, the owner has set this menu to: " + llList2String(MENUCONTROL_TYPES, MENUCONTROL_INDEX), [], -585868);
|
||||
}
|
||||
}
|
||||
options_menu()
|
||||
{
|
||||
string text;
|
||||
list menu_items = ["[BACK]"];
|
||||
text = "Prop options:\n";
|
||||
if (avprop_is_copy_transfer(MASK_OWNER) && prim_is_mod())
|
||||
{
|
||||
menu_items += ["[NEW]", "[DUMP]"];
|
||||
text += "\n[NEW] = Add a new prop.";
|
||||
text += "\n[DUMP] = Read settings to chat.";
|
||||
}
|
||||
menu_items += ["[SAVE]", "[CLEAR]", "[SECURITY]", "[RESET]"];
|
||||
text += "\n[SAVE] = Save prop positions.";
|
||||
text += "\n[CLEAR] = Clear props.";
|
||||
text += "\n[SECURITY] = Menu security.";
|
||||
text += "\n[RESET] = Reload notecard.";
|
||||
dialog(llGetOwner(), text, menu_items);
|
||||
}
|
||||
choice_menu(list options, string menu_text)
|
||||
{
|
||||
last_text = menu_text;
|
||||
choosing = TRUE;
|
||||
menu_text = "\n(Page " + (string)(menu_page + 1) + "/" + (string)menu_pages + ")\n" + menu_text + "\n\n";
|
||||
list menu_items;
|
||||
integer i;
|
||||
if (llGetListLength(options) == 0)
|
||||
{
|
||||
menu_text = "\nNo items of required type in the prim inventory.";
|
||||
menu_items = ["[BACK]"];
|
||||
}
|
||||
else
|
||||
{
|
||||
integer cutoff = 65;
|
||||
integer all_options_length = llStringLength(llDumpList2String(options, ""));
|
||||
integer total_need_to_cut = 412 - all_options_length;
|
||||
if (total_need_to_cut < 0)
|
||||
{
|
||||
cutoff = 43;
|
||||
}
|
||||
for (i = 0; i < llGetListLength(options); i++)
|
||||
{
|
||||
menu_items += (string)(i + 1);
|
||||
string item = llList2String(options, i);
|
||||
if (llStringLength(item) > cutoff)
|
||||
{
|
||||
item = llGetSubString(item, 0, cutoff) + "..";
|
||||
}
|
||||
menu_text += (string)(i + 1) + "." + item + "\n";
|
||||
}
|
||||
while (llGetListLength(menu_items) < number_per_page)
|
||||
{
|
||||
menu_items += " ";
|
||||
}
|
||||
menu_items += ["[BACK]", "[<<]", "[>>]"];
|
||||
}
|
||||
dialog(llGetOwner(), menu_text, menu_items);
|
||||
}
|
||||
list get_choices(integer page)
|
||||
{
|
||||
menu_page = page;
|
||||
list options;
|
||||
integer i;
|
||||
integer start = number_per_page * menu_page;
|
||||
integer end = start + number_per_page;
|
||||
integer type = INVENTORY_OBJECT;
|
||||
i = start;
|
||||
while (llGetListLength(options) + start < end && i < llGetInventoryNumber(type))
|
||||
{
|
||||
options += llGetInventoryName(type, i);
|
||||
i++;
|
||||
}
|
||||
i = llGetInventoryNumber(type);
|
||||
menu_pages = llCeil((float)i / number_per_page);
|
||||
return options;
|
||||
}
|
||||
remove_script(string reason)
|
||||
{
|
||||
string message = "\n" + llGetScriptName() + " ==Script Removed==\n\n" + reason;
|
||||
llDialog(llGetOwner(), message, ["OK"], -3675);
|
||||
llInstantMessage(llGetOwner(), message);
|
||||
llRemoveInventory(llGetScriptName());
|
||||
}
|
||||
integer prop_menu(integer return_pages, key av)
|
||||
{
|
||||
choosing = FALSE;
|
||||
choice = "";
|
||||
integer total_items;
|
||||
integer i = current_menu + 1;
|
||||
while (i < llGetListLength(MENU_LIST) && llSubStringIndex(llList2String(MENU_LIST, i), "M:") != 0)
|
||||
{
|
||||
total_items++;
|
||||
i++;
|
||||
}
|
||||
list menu_items2;
|
||||
if (current_menu != -1)
|
||||
{
|
||||
menu_items2 = ["[BACK]"] + menu_items2;
|
||||
}
|
||||
list menu_items1;
|
||||
if (llGetInventoryType(prop_script) == INVENTORY_SCRIPT)
|
||||
{
|
||||
menu_items2 += ["[OWNER]"];
|
||||
}
|
||||
if (total_items + llGetListLength(menu_items2) > 12)
|
||||
{
|
||||
menu_items2 += ["[<<]", "[>>]"];
|
||||
}
|
||||
integer items_per_page = 12 - llGetListLength(menu_items2);
|
||||
integer page_start = current_menu + 1 + menu_page * items_per_page;
|
||||
for (i = page_start; i < page_start + items_per_page; i++)
|
||||
{
|
||||
if (i < llGetListLength(MENU_LIST))
|
||||
{
|
||||
if (llSubStringIndex(llList2String(MENU_LIST, i), "M:") != -1)
|
||||
{
|
||||
jump end;
|
||||
}
|
||||
if (llListFindList(["T:", "S:", "B:"], [llGetSubString(llList2String(MENU_LIST, i), 0, 1)]) == -1)
|
||||
{
|
||||
menu_items1 += llList2String(MENU_LIST, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_items1 += llGetSubString(llList2String(llParseString2List(llList2String(MENU_LIST, i), ["|"], []), 0), 2, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@end;
|
||||
if (return_pages)
|
||||
{
|
||||
integer pages = llCeil(total_items) / (12 - llGetListLength(menu_items2));
|
||||
if (total_items % (12 - llGetListLength(menu_items2)) == 0)
|
||||
{
|
||||
pages--;
|
||||
}
|
||||
return pages;
|
||||
}
|
||||
if (llList2String(menu_items2, 0) == "[BACK]")
|
||||
{
|
||||
menu_items1 = ["[BACK]"] + menu_items1;
|
||||
menu_items2 = llDeleteSubList(menu_items2, 0, 0);
|
||||
}
|
||||
menu_channel = ((integer)llFrand(2147483646) + 1) * -1;
|
||||
llListenRemove(listen_handle);
|
||||
listen_handle = llListen(menu_channel, "", av, "");
|
||||
dialog(av, custom_text, menu_items1 + menu_items2);
|
||||
return 0;
|
||||
}
|
||||
string strReplace(string str, string search, string replace)
|
||||
{
|
||||
return llDumpList2String(llParseStringKeepNulls((str = "") + str, [search], []), replace);
|
||||
}
|
||||
naming()
|
||||
{
|
||||
llTextBox(llGetOwner(), "\nPlease type a button name for your prop\nProp: " + choice, menu_channel);
|
||||
}
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
if (llSubStringIndex(llGetScriptName(), " ") != -1)
|
||||
{
|
||||
remove_script("Use only one copy of this script!");
|
||||
}
|
||||
check_avsit();
|
||||
notecard_key = llGetInventoryKey(notecard_name);
|
||||
Out(0, "Loading...");
|
||||
notecard_query = llGetNotecardLine(notecard_name, notecard_line);
|
||||
}
|
||||
timer()
|
||||
{
|
||||
llListenRemove(listen_handle);
|
||||
}
|
||||
listen(integer listen_channel, string name, key id, string msg)
|
||||
{
|
||||
if (choice)
|
||||
{
|
||||
if (msg == "")
|
||||
{
|
||||
naming();
|
||||
}
|
||||
else
|
||||
{
|
||||
integer perms = llGetInventoryPermMask(choice, MASK_NEXT);
|
||||
if (!(perms & PERM_COPY))
|
||||
{
|
||||
llSay(0, "Could not add prop '" + choice + "'. Props and their content must be COPY-OK for NEXT owner.");
|
||||
}
|
||||
else
|
||||
{
|
||||
llMessageLinked(LINK_THIS, 90173, msg, choice);
|
||||
MENU_LIST = ["B:" + msg] + MENU_LIST;
|
||||
DATA_LIST = [90200] + DATA_LIST;
|
||||
}
|
||||
choice = "";
|
||||
options_menu();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (choosing && llListFindList(["1", "2", "3", "4", "5", "6", "7", "8", "9"], [msg]) != -1)
|
||||
{
|
||||
choosing = FALSE;
|
||||
choice = llList2String(get_choices(menu_page), (integer)msg - 1);
|
||||
naming();
|
||||
return;
|
||||
}
|
||||
if (msg == "[SECURITY]")
|
||||
{
|
||||
if (id == llGetOwner())
|
||||
{
|
||||
dialog(llGetOwner(), "Who is allowed to control this menu?", MENUCONTROL_TYPES);
|
||||
}
|
||||
else
|
||||
{
|
||||
llRegionSayTo(id, 0, "Sorry, only the owner can use this.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
integer mindex_test = llListFindList(MENU_LIST, ["M:" + msg]);
|
||||
if (mindex_test != -1)
|
||||
{
|
||||
menu_page = 0;
|
||||
current_menu = mindex_test;
|
||||
}
|
||||
mindex_test = llListFindList(MENU_LIST, ["B:" + msg]);
|
||||
if (mindex_test != -1)
|
||||
{
|
||||
list button_data = llParseStringKeepNulls(llList2String(DATA_LIST, mindex_test), ["<22>"], []);
|
||||
if (llList2String(button_data, 1))
|
||||
{
|
||||
msg = llList2String(button_data, 1);
|
||||
}
|
||||
if (llList2String(button_data, 2))
|
||||
{
|
||||
id = llList2String(button_data, 2);
|
||||
}
|
||||
llMessageLinked(LINK_SET, (integer)llList2String(button_data, 0), msg, id);
|
||||
return;
|
||||
}
|
||||
else if (msg == "[>>]" || msg == "[<<]")
|
||||
{
|
||||
if (choosing)
|
||||
{
|
||||
if (msg == "[>>]")
|
||||
{
|
||||
menu_page++;
|
||||
if (menu_page >= menu_pages)
|
||||
{
|
||||
menu_page = 0;
|
||||
}
|
||||
}
|
||||
else if (msg == "[<<]")
|
||||
{
|
||||
menu_page--;
|
||||
if (menu_page < 0)
|
||||
{
|
||||
menu_page = menu_pages - 1;
|
||||
}
|
||||
}
|
||||
choice_menu(get_choices(menu_page), last_text);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (msg == "[<<]")
|
||||
{
|
||||
menu_page--;
|
||||
if (menu_page < 0)
|
||||
{
|
||||
menu_page = prop_menu(TRUE, NULL_KEY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
menu_page++;
|
||||
if (menu_page > prop_menu(TRUE, NULL_KEY))
|
||||
{
|
||||
menu_page = 0;
|
||||
}
|
||||
}
|
||||
prop_menu(FALSE, id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (msg == "[BACK]")
|
||||
{
|
||||
menu_page = 0;
|
||||
current_menu = -1;
|
||||
}
|
||||
else if (msg == "[NEW]")
|
||||
{
|
||||
llMessageLinked(LINK_THIS, 90200, "", "");
|
||||
choice_menu(get_choices(0), "Please choose your prop:\n\n(Props must include the [AV]object script!)");
|
||||
return;
|
||||
}
|
||||
else if (msg == "[DUMP]")
|
||||
{
|
||||
Readout_Say("");
|
||||
Readout_Say("--✄--COPY BELOW INTO \"AVpos\" NOTECARD--✄--");
|
||||
Readout_Say("");
|
||||
if (custom_text)
|
||||
{
|
||||
Readout_Say("TEXT " + strReplace(custom_text, "\n", "\\n"));
|
||||
}
|
||||
integer i;
|
||||
for (i = 0; i < llGetListLength(MENU_LIST); i++)
|
||||
{
|
||||
list change_me = llParseString2List(llList2String(MENU_LIST, i), [":"], []);
|
||||
if (llGetListLength(change_me) == 2)
|
||||
{
|
||||
if (llList2String(change_me, 0) == "M")
|
||||
{
|
||||
Readout_Say("MENU " + llGetSubString(llList2String(change_me, 1), 0, -2));
|
||||
}
|
||||
else if (llList2String(change_me, 0) == "T")
|
||||
{
|
||||
Readout_Say("TOMENU " + llGetSubString(llList2String(change_me, 1), 0, -2));
|
||||
}
|
||||
else if (llList2String(change_me, 0) == "B")
|
||||
{
|
||||
list l = [llList2String(change_me, 1), strReplace(strReplace(llList2String(DATA_LIST, i), "90200", ""), "<22>", "|")];
|
||||
if (llList2String(l, 1) == "")
|
||||
{
|
||||
l = llList2List(l, 0, 0);
|
||||
}
|
||||
string end = llDumpList2String(l, "|");
|
||||
Readout_Say("BUTTON " + end);
|
||||
}
|
||||
}
|
||||
}
|
||||
llMessageLinked(LINK_THIS, 90020, "0", prop_script);
|
||||
return;
|
||||
}
|
||||
else if (msg == "[SAVE]" && id == llGetOwner())
|
||||
{
|
||||
llMessageLinked(LINK_SET, 90101, "0|" + msg, "");
|
||||
options_menu();
|
||||
return;
|
||||
}
|
||||
else if (msg == "[CLEAR]")
|
||||
{
|
||||
Out(0, "Props have been cleared!");
|
||||
llMessageLinked(LINK_THIS, 90200, "", "");
|
||||
}
|
||||
else if (msg == "[RESET]")
|
||||
{
|
||||
llMessageLinked(LINK_THIS, 90200, "", "");
|
||||
llSleep(1);
|
||||
llResetOtherScript(prop_script);
|
||||
llResetScript();
|
||||
return;
|
||||
}
|
||||
else if (msg == "[BACK]")
|
||||
{
|
||||
}
|
||||
else if (msg == "[OWNER]")
|
||||
{
|
||||
if (id == llGetOwner())
|
||||
{
|
||||
options_menu();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
llRegionSayTo(id, 0, "Sorry, only the owner can use this.");
|
||||
}
|
||||
}
|
||||
else if (id == llGetOwner() && llListFindList(MENUCONTROL_TYPES, [msg]) != -1)
|
||||
{
|
||||
MENUCONTROL_INDEX = llListFindList(MENUCONTROL_TYPES, [msg]);
|
||||
Out(0, "Menu access set to: " + llList2String(MENUCONTROL_TYPES, MENUCONTROL_INDEX));
|
||||
if (llGetInventoryType(prop_script) == INVENTORY_SCRIPT)
|
||||
{
|
||||
options_menu();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
prop_menu(FALSE, id);
|
||||
}
|
||||
touch_start(integer touched)
|
||||
{
|
||||
if (MTYPE < 3)
|
||||
{
|
||||
menu_check(llDetectedName(0), llDetectedKey(0));
|
||||
}
|
||||
}
|
||||
changed(integer change)
|
||||
{
|
||||
if (change & CHANGED_INVENTORY)
|
||||
{
|
||||
if (llGetInventoryKey(notecard_name) != notecard_key)
|
||||
{
|
||||
llResetScript();
|
||||
}
|
||||
check_avsit();
|
||||
}
|
||||
}
|
||||
link_message(integer sender, integer num, string msg, key id)
|
||||
{
|
||||
if (sender == llGetLinkNumber())
|
||||
{
|
||||
if (num == 90005)
|
||||
{
|
||||
menu_check(llKey2Name(id), id);
|
||||
}
|
||||
else if (num == 90022)
|
||||
{
|
||||
Readout_Say(msg);
|
||||
}
|
||||
else if (num == 90021)
|
||||
{
|
||||
Readout_Say("");
|
||||
Readout_Say("--✄--COPY ABOVE INTO \"AVpos\" NOTECARD--✄--");
|
||||
Readout_Say("");
|
||||
}
|
||||
}
|
||||
}
|
||||
dataserver(key query_id, string data)
|
||||
{
|
||||
if (query_id == notecard_query)
|
||||
{
|
||||
if (data == EOF)
|
||||
{
|
||||
Out(0, (string)llGetListLength(MENU_LIST) + " menu items Ready, Memory: " + (string)llGetFreeMemory());
|
||||
llPassTouches(FALSE);
|
||||
if (MTYPE == 3)
|
||||
{
|
||||
llPassTouches(TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data = llGetSubString(data, llSubStringIndex(data, "◆") + 1, -1);
|
||||
data = llStringTrim(data, STRING_TRIM);
|
||||
string command = llGetSubString(data, 0, llSubStringIndex(data, " ") - 1);
|
||||
list parts = llParseStringKeepNulls(llGetSubString(data, llSubStringIndex(data, " ") + 1, -1), [" | ", " |", "| ", "|"], []);
|
||||
string part0 = llStringTrim(llList2String(parts, 0), STRING_TRIM);
|
||||
string part1 = llList2String(parts, 1);
|
||||
if (llGetListLength(parts) > 1)
|
||||
{
|
||||
part1 = llStringTrim(llDumpList2String(llList2List(parts, 1, -1), "<22>"), STRING_TRIM);
|
||||
}
|
||||
if (command == "TEXT")
|
||||
{
|
||||
custom_text = llDumpList2String(llParseStringKeepNulls(part0, ["\\n"], []), "\n");
|
||||
}
|
||||
part0 = llGetSubString(part0, 0, 22);
|
||||
if (command == "MENU")
|
||||
{
|
||||
MENU_LIST += ["M:" + part0 + "*"];
|
||||
DATA_LIST += "";
|
||||
}
|
||||
else if (command == "TOMENU")
|
||||
{
|
||||
MENU_LIST += ["T:" + part0 + "*"];
|
||||
DATA_LIST += "";
|
||||
}
|
||||
else if (command == "BUTTON")
|
||||
{
|
||||
MENU_LIST += ["B:" + part0];
|
||||
if (part1 == "")
|
||||
{
|
||||
part1 = "90200";
|
||||
}
|
||||
DATA_LIST += part1;
|
||||
}
|
||||
else if (command == "MTYPE")
|
||||
{
|
||||
MTYPE = (integer)part0;
|
||||
}
|
||||
notecard_query = llGetNotecardLine(notecard_name, ++notecard_line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
241
AVsitter2/Plugins/AVprop/[AV]object.lsl
Normal file
241
AVsitter2/Plugins/AVprop/[AV]object.lsl
Normal file
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* 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 (c) 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* The release version of the [AV]object Script has the original AVsitter experience
|
||||
* enabled. Scripts with this experience may not be shared in full perms form.
|
||||
* Please support further development of AVsitter by not sharing it!
|
||||
* If you acquired this script from someone else, please support the
|
||||
* developers by purchasing AVsitter (see https://avsitter.github.io)
|
||||
* and also obtain the benefit of automatic updates.
|
||||
*/
|
||||
|
||||
string version = "2.020";
|
||||
integer comm_channel;
|
||||
integer local_attach_channel = -2907539;
|
||||
integer listen_handle;
|
||||
integer prop_type;
|
||||
integer prop_id;
|
||||
integer prop_point;
|
||||
integer experience_denied_reason;
|
||||
key originalowner;
|
||||
key give_prop_warning_request;
|
||||
unsit_all()
|
||||
{
|
||||
integer i = llGetNumberOfPrims();
|
||||
while (llGetAgentSize(llGetLinkKey(i)))
|
||||
{
|
||||
llUnSit(llGetLinkKey(i));
|
||||
i--;
|
||||
}
|
||||
}
|
||||
integer verbose = 5;
|
||||
Out(integer level, string out)
|
||||
{
|
||||
if (verbose >= level)
|
||||
{
|
||||
llOwnerSay(llGetScriptName() + "[" + version + "] " + out);
|
||||
}
|
||||
}
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
}
|
||||
on_rez(integer start)
|
||||
{
|
||||
if (start)
|
||||
{
|
||||
state prop;
|
||||
}
|
||||
}
|
||||
}
|
||||
state prop
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
if (llGetLinkNumber() < 2)
|
||||
{
|
||||
if (llGetStartParameter() <= -10000000)
|
||||
{
|
||||
string start_param = (string)llGetStartParameter();
|
||||
prop_type = (integer)llGetSubString(start_param, -1, -1);
|
||||
prop_point = (integer)llGetSubString(start_param, -3, -2);
|
||||
prop_id = (integer)llGetSubString(start_param, -5, -4);
|
||||
comm_channel = (integer)llGetSubString(start_param, 0, -6);
|
||||
listen_handle = llListen(comm_channel, "", "", "");
|
||||
llSay(comm_channel, "REZ|" + (string)prop_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
if (prop_type != 2 && prop_type != 1)
|
||||
{
|
||||
if (llGetInventoryType("[AV]sitA") == INVENTORY_NONE)
|
||||
{
|
||||
llSetClickAction(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llSetClickAction(CLICK_ACTION_TOUCH);
|
||||
}
|
||||
}
|
||||
attach(key id)
|
||||
{
|
||||
if (comm_channel)
|
||||
{
|
||||
if (llGetAttached())
|
||||
{
|
||||
llListen(local_attach_channel, "", "", "");
|
||||
llSay(comm_channel, "ATTACHED|" + (string)prop_id);
|
||||
llSay(local_attach_channel, "LOCAT|" + (string)llGetAttached());
|
||||
if (experience_denied_reason == 17)
|
||||
{
|
||||
if (llGetOwner() == originalowner)
|
||||
{
|
||||
list details = llGetExperienceDetails("");
|
||||
if (llList2String(details, 3) == "17")
|
||||
{
|
||||
llSay(comm_channel, "NAG|" + llList2String(details, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llSay(comm_channel, "DETACHED|" + (string)prop_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
touch_start(integer touched)
|
||||
{
|
||||
if ((!llGetAttached()) && (prop_type == 2 || prop_type == 1))
|
||||
{
|
||||
llRequestExperiencePermissions(llDetectedKey(0), "");
|
||||
}
|
||||
}
|
||||
run_time_permissions(integer permissions)
|
||||
{
|
||||
if (permissions & PERMISSION_ATTACH)
|
||||
{
|
||||
if (llGetAttached())
|
||||
{
|
||||
llDetachFromAvatar();
|
||||
}
|
||||
else
|
||||
{
|
||||
llAttachToAvatarTemp(prop_point);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llSay(comm_channel, "DEREZ|" + (string)prop_id);
|
||||
llDie();
|
||||
}
|
||||
}
|
||||
experience_permissions(key target_id)
|
||||
{
|
||||
if (llGetAttached())
|
||||
{
|
||||
llDetachFromAvatar();
|
||||
}
|
||||
else
|
||||
{
|
||||
llAttachToAvatarTemp(prop_point);
|
||||
}
|
||||
}
|
||||
experience_permissions_denied(key agent_id, integer reason)
|
||||
{
|
||||
originalowner = llGetOwner();
|
||||
experience_denied_reason = reason;
|
||||
llRequestPermissions(agent_id, PERMISSION_ATTACH);
|
||||
}
|
||||
on_rez(integer start)
|
||||
{
|
||||
if (!llGetAttached())
|
||||
{
|
||||
state restart_prop;
|
||||
}
|
||||
}
|
||||
listen(integer channel, string name, key id, string message)
|
||||
{
|
||||
list data = llParseString2List(message, ["|"], []);
|
||||
string command = llList2String(data, 0);
|
||||
if (llList2String(data, 0) == "LOCAT" && llGetOwnerKey(id) == llGetOwner() && llList2String(data, 1) == (string)llGetAttached())
|
||||
{
|
||||
llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
|
||||
}
|
||||
else if (command == "ATTACHTO" && prop_type == 1 && (key)llList2String(data, 2) == llGetKey())
|
||||
{
|
||||
if (llGetAgentSize((key)llList2String(data, 1)) == ZERO_VECTOR)
|
||||
{
|
||||
llSay(comm_channel, "DEREZ|" + (string)prop_id);
|
||||
llDie();
|
||||
}
|
||||
else
|
||||
{
|
||||
llRequestExperiencePermissions((key)llList2String(data, 1), "");
|
||||
}
|
||||
}
|
||||
else if (llGetSubString(command, 0, 3) == "REM_")
|
||||
{
|
||||
integer remove;
|
||||
if (command == "REM_ALL")
|
||||
{
|
||||
remove = TRUE;
|
||||
}
|
||||
else if (command == "REM_INDEX" || (command == "REM_WORLD" && (!llGetAttached())))
|
||||
{
|
||||
if (~llListFindList(data, [(string)prop_id]))
|
||||
{
|
||||
remove = TRUE;
|
||||
}
|
||||
}
|
||||
else if (llGetAttached() && command == "REM_WORN" && (key)llList2String(data, 1) == llGetOwner())
|
||||
{
|
||||
remove = TRUE;
|
||||
}
|
||||
if (remove)
|
||||
{
|
||||
if (llGetAttached())
|
||||
{
|
||||
llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (llGetAgentSize(llGetLinkKey(llGetNumberOfPrims())))
|
||||
{
|
||||
unsit_all();
|
||||
llSleep(1);
|
||||
}
|
||||
llSay(comm_channel, "DEREZ|" + (string)prop_id);
|
||||
llDie();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (message == "PROPSEARCH" && (!llGetAttached()))
|
||||
{
|
||||
llSay(comm_channel, "SAVEPROP|" + (string)prop_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
state restart_prop
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
state prop;
|
||||
}
|
||||
}
|
578
AVsitter2/Plugins/AVprop/[AV]prop.lsl
Normal file
578
AVsitter2/Plugins/AVprop/[AV]prop.lsl
Normal file
|
@ -0,0 +1,578 @@
|
|||
/*
|
||||
* 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 (c) 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 version = "2.2";
|
||||
string notecard_name = "AVpos";
|
||||
string main_script = "[AV]sitA";
|
||||
key key_request;
|
||||
integer comm_channel;
|
||||
integer WARN = 1;
|
||||
key notecard_key;
|
||||
key notecard_query;
|
||||
integer notecard_line;
|
||||
integer notecard_section;
|
||||
integer listen_handle;
|
||||
list prop_triggers;
|
||||
list prop_types;
|
||||
list prop_objects;
|
||||
list prop_positions;
|
||||
list prop_rotations;
|
||||
list prop_groups;
|
||||
list prop_points;
|
||||
list sequential_prop_groups;
|
||||
integer HAVENTNAGGED = TRUE;
|
||||
list SITTERS;
|
||||
list SITTER_POSES;
|
||||
list ATTACH_POINTS = [ATTACH_CHEST, "chest", ATTACH_HEAD, "head", ATTACH_LSHOULDER, "left shoulder", ATTACH_RSHOULDER, "right shoulder", ATTACH_LHAND, "left hand", ATTACH_RHAND, "right hand", ATTACH_LFOOT, "left foot", ATTACH_RFOOT, "right foot", ATTACH_BACK, "back", ATTACH_PELVIS, "pelvis", ATTACH_MOUTH, "mouth", ATTACH_CHIN, "chin", ATTACH_LEAR, "left ear", ATTACH_REAR, "right ear", ATTACH_LEYE, "left eye", ATTACH_REYE, "right eye", ATTACH_NOSE, "nose", ATTACH_RUARM, "right upper arm", ATTACH_RLARM, "right lower arm", ATTACH_LUARM, "left upper arm", ATTACH_LLARM, "left lower arm", ATTACH_RHIP, "right hip", ATTACH_RULEG, "right upper leg", ATTACH_RLLEG, "right lower leg", ATTACH_LHIP, "left hip", ATTACH_LULEG, "left upper leg", ATTACH_LLLEG, "left lower leg", ATTACH_BELLY, "stomach", ATTACH_LEFT_PEC, "left pectoral", ATTACH_RIGHT_PEC, "right pectoral", ATTACH_HUD_CENTER_2, "HUD center 2", ATTACH_HUD_TOP_RIGHT, "HUD top right", ATTACH_HUD_TOP_CENTER, "HUD top", ATTACH_HUD_TOP_LEFT, "HUD top left", ATTACH_HUD_CENTER_1, "HUD center", ATTACH_HUD_BOTTOM_LEFT, "HUD bottom left", ATTACH_HUD_BOTTOM, "HUD bottom", ATTACH_HUD_BOTTOM_RIGHT, "HUD bottom right", 39, "neck", 40, "avatar center"];
|
||||
integer verbose = 5;
|
||||
Out(integer level, string out)
|
||||
{
|
||||
if (verbose >= level)
|
||||
{
|
||||
llOwnerSay(llGetScriptName() + "[" + version + "] " + out);
|
||||
}
|
||||
}
|
||||
integer IsInteger(string data)
|
||||
{
|
||||
return llParseString2List((string)llParseString2List(data, ["8", "9"], []), ["0", "1", "2", "3", "4", "5", "6", "7"], []) == [] && data != "";
|
||||
}
|
||||
integer get_number_of_scripts()
|
||||
{
|
||||
integer i = 1;
|
||||
while (llGetInventoryType(main_script + " " + (string)i) == INVENTORY_SCRIPT)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
integer get_point(string text)
|
||||
{
|
||||
integer i;
|
||||
for (i = 1; i < llGetListLength(ATTACH_POINTS); i = i + 2)
|
||||
{
|
||||
if (~llSubStringIndex(llToUpper(text), llToUpper(llList2String(ATTACH_POINTS, i))))
|
||||
{
|
||||
return llList2Integer(ATTACH_POINTS, i - 1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
rez_prop(integer index)
|
||||
{
|
||||
integer type = llList2Integer(prop_types, index);
|
||||
string object = llList2String(prop_objects, index);
|
||||
if (object != "")
|
||||
{
|
||||
vector pos = llList2Vector(prop_positions, index) * llGetRot() + llGetPos();
|
||||
rotation rot = llEuler2Rot(llList2Vector(prop_rotations, index) * DEG_TO_RAD) * llGetRot();
|
||||
integer pt = get_point(llList2String(prop_points, index));
|
||||
string point = (string)pt;
|
||||
if (llStringLength(point) == 1)
|
||||
{
|
||||
point = "0" + point;
|
||||
}
|
||||
string prop_id = (string)index;
|
||||
if (llStringLength(prop_id) == 1)
|
||||
{
|
||||
prop_id = "0" + prop_id;
|
||||
}
|
||||
integer int = (integer)((string)comm_channel + prop_id + point + (string)type);
|
||||
if (llGetInventoryType(object) != INVENTORY_OBJECT)
|
||||
{
|
||||
llSay(0, "Could not find prop '" + object + "'.");
|
||||
return;
|
||||
}
|
||||
integer perms = llGetInventoryPermMask(object, MASK_NEXT);
|
||||
string next = " for NEXT owner";
|
||||
if (WARN == 2)
|
||||
{
|
||||
next = "";
|
||||
perms = llGetInventoryPermMask(object, MASK_OWNER);
|
||||
}
|
||||
if (type == 0 || type == 3)
|
||||
{
|
||||
if (!(perms & PERM_COPY))
|
||||
{
|
||||
llSay(0, "Can't rez '" + object + "'. Props and their content must be COPY-OK" + next);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (type > 0)
|
||||
{
|
||||
if ((!(perms & PERM_COPY)) || (!(perms & PERM_TRANSFER)))
|
||||
{
|
||||
llSay(0, "Can't rez '" + object + "'. Attachment props and their content must be COPY-TRANSFER" + next);
|
||||
return;
|
||||
}
|
||||
}
|
||||
llRezAtRoot(object, pos, ZERO_VECTOR, rot, int);
|
||||
}
|
||||
}
|
||||
send_command(string command)
|
||||
{
|
||||
llRegionSay(comm_channel, command);
|
||||
llSay(comm_channel, command);
|
||||
}
|
||||
remove_all_props()
|
||||
{
|
||||
send_command("REM_ALL");
|
||||
}
|
||||
rez_props_by_trigger(string pose_name)
|
||||
{
|
||||
integer i;
|
||||
for (; i < llGetListLength(prop_triggers); i++)
|
||||
{
|
||||
if (llList2String(prop_triggers, i) == pose_name)
|
||||
{
|
||||
rez_prop(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
list get_props_by_pose(string pose_name)
|
||||
{
|
||||
list props_to_do;
|
||||
integer i;
|
||||
for (; i < llGetListLength(prop_triggers); i++)
|
||||
{
|
||||
if (llList2String(prop_triggers, i) == pose_name)
|
||||
{
|
||||
props_to_do += i;
|
||||
}
|
||||
}
|
||||
return props_to_do;
|
||||
}
|
||||
remove_props_by_sitter(string sitter, integer remove_type3)
|
||||
{
|
||||
list text;
|
||||
integer i;
|
||||
for (; i < llGetListLength(prop_triggers); i++)
|
||||
{
|
||||
if (llSubStringIndex(llList2String(prop_triggers, i), sitter + "|") == 0)
|
||||
{
|
||||
if (llList2Integer(prop_types, i) != 3 || remove_type3)
|
||||
{
|
||||
text += [i];
|
||||
}
|
||||
}
|
||||
}
|
||||
string command = "REM_INDEX";
|
||||
if (llGetInventoryType(main_script) != INVENTORY_SCRIPT)
|
||||
{
|
||||
command = "REM_WORLD";
|
||||
}
|
||||
if (text)
|
||||
{
|
||||
send_command(llDumpList2String([command] + text, "|"));
|
||||
}
|
||||
}
|
||||
remove_worn(key av)
|
||||
{
|
||||
send_command(llDumpList2String(["REM_WORN", av], "|"));
|
||||
}
|
||||
remove_sitter_props_by_pose(string sitter_pose, integer remove_type3)
|
||||
{
|
||||
list text;
|
||||
integer i;
|
||||
for (; i < llGetListLength(prop_triggers); i++)
|
||||
{
|
||||
if (llList2String(prop_triggers, i) == sitter_pose)
|
||||
{
|
||||
if (llList2Integer(prop_types, i) != 3 || remove_type3)
|
||||
{
|
||||
text += [i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (text)
|
||||
{
|
||||
send_command(llDumpList2String(["REM_INDEX"] + text, "|"));
|
||||
}
|
||||
}
|
||||
remove_sitter_props_by_pose_group(string msg)
|
||||
{
|
||||
list props = get_props_by_pose(msg);
|
||||
list groups;
|
||||
integer i;
|
||||
for (; i < llGetListLength(props); i++)
|
||||
{
|
||||
string prop_group = llList2String(prop_groups, llList2Integer(props, i));
|
||||
if (!~llListFindList(groups, [prop_group]))
|
||||
{
|
||||
groups += prop_group;
|
||||
remove_props_by_group(llListFindList(sequential_prop_groups, [prop_group]));
|
||||
}
|
||||
}
|
||||
}
|
||||
remove_props_by_group(integer gp)
|
||||
{
|
||||
list text;
|
||||
string group = llList2String(sequential_prop_groups, gp);
|
||||
integer i;
|
||||
for (; i < llGetListLength(prop_groups); i++)
|
||||
{
|
||||
if (llList2String(prop_groups, i) == group)
|
||||
{
|
||||
text += [i];
|
||||
}
|
||||
}
|
||||
string command = "REM_INDEX";
|
||||
if (llGetInventoryType(main_script) != INVENTORY_SCRIPT)
|
||||
{
|
||||
command = "REM_WORLD";
|
||||
}
|
||||
if (text)
|
||||
{
|
||||
send_command(llDumpList2String([command] + text, "|"));
|
||||
}
|
||||
}
|
||||
Readout_Say(string say)
|
||||
{
|
||||
llSleep(0.2);
|
||||
llMessageLinked(LINK_THIS, 90022, say, "");
|
||||
}
|
||||
init_sitters()
|
||||
{
|
||||
SITTERS = [];
|
||||
SITTER_POSES = [];
|
||||
integer i;
|
||||
for (i = 0; i < get_number_of_scripts(); i++)
|
||||
{
|
||||
SITTERS += NULL_KEY;
|
||||
SITTER_POSES += "";
|
||||
}
|
||||
}
|
||||
init_channel()
|
||||
{
|
||||
llListenRemove(listen_handle);
|
||||
comm_channel = ((integer)llFrand(8999) + 1000) * -1;
|
||||
listen_handle = llListen(comm_channel, "", "", "");
|
||||
}
|
||||
string element(string text, integer x)
|
||||
{
|
||||
return llList2String(llParseStringKeepNulls(text, ["|"], []), x);
|
||||
}
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
Out(0, "Mem=" + (string)(65536 - llGetUsedMemory()));
|
||||
init_sitters();
|
||||
init_channel();
|
||||
notecard_key = llGetInventoryKey(notecard_name);
|
||||
if (llGetInventoryType(notecard_name) == INVENTORY_NOTECARD)
|
||||
{
|
||||
Out(0, "Loading...");
|
||||
notecard_query = llGetNotecardLine(notecard_name, 0);
|
||||
}
|
||||
}
|
||||
on_rez(integer start)
|
||||
{
|
||||
init_channel();
|
||||
}
|
||||
link_message(integer sender, integer num, string msg, key id)
|
||||
{
|
||||
if (sender == llGetLinkNumber())
|
||||
{
|
||||
if (num == 90045)
|
||||
{
|
||||
list data = llParseStringKeepNulls(msg, ["|"], []);
|
||||
integer sitter = (integer)llList2String(data, 0);
|
||||
if (id == llList2Key(SITTERS, sitter))
|
||||
{
|
||||
remove_sitter_props_by_pose(llList2String(SITTER_POSES, sitter), FALSE);
|
||||
string given_posename = llList2String(data, 1);
|
||||
given_posename = (string)sitter + "|" + given_posename;
|
||||
SITTER_POSES = llListReplaceList(SITTER_POSES, [given_posename], sitter, sitter);
|
||||
remove_sitter_props_by_pose_group(given_posename);
|
||||
rez_props_by_trigger(given_posename);
|
||||
}
|
||||
}
|
||||
else if (num == 90200 || num == 90220)
|
||||
{
|
||||
list ids = llParseStringKeepNulls(id, ["|"], []);
|
||||
key sitting_av_or_sitter = (key)llList2String(ids, -1);
|
||||
if (llGetInventoryType(main_script) != INVENTORY_SCRIPT)
|
||||
{
|
||||
SITTERS = [sitting_av_or_sitter];
|
||||
}
|
||||
integer i;
|
||||
if (!llSubStringIndex(msg, "remprop_"))
|
||||
{
|
||||
for (; i < llGetListLength(SITTERS); i++)
|
||||
{
|
||||
if (llList2Key(SITTERS, i) == sitting_av_or_sitter || id == "" || (string)sitting_av_or_sitter == (string)i)
|
||||
{
|
||||
remove_sitter_props_by_pose((string)i + "|" + llGetSubString(msg, 8, -1), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
integer flag;
|
||||
for (; i < llGetListLength(SITTERS); i++)
|
||||
{
|
||||
if (~llListFindList(prop_triggers, [(string)i + "|" + msg]))
|
||||
{
|
||||
flag = TRUE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < llGetListLength(SITTERS); i++)
|
||||
{
|
||||
if (llList2Key(SITTERS, i) == sitting_av_or_sitter || id == "" || (string)sitting_av_or_sitter == (string)i)
|
||||
{
|
||||
integer index = llListFindList(prop_triggers, [(string)i + "|" + msg]);
|
||||
if (!~index)
|
||||
{
|
||||
if (llGetInventoryType(main_script) != INVENTORY_SCRIPT)
|
||||
{
|
||||
remove_all_props();
|
||||
}
|
||||
else if (!flag)
|
||||
{
|
||||
remove_props_by_sitter((string)i, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_sitter_props_by_pose_group((string)i + "|" + msg);
|
||||
rez_props_by_trigger((string)i + "|" + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sitting_av_or_sitter)
|
||||
{
|
||||
if (num == 90200)
|
||||
{
|
||||
llMessageLinked(LINK_THIS, 90005, "", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (num == 90101)
|
||||
{
|
||||
list data = llParseString2List(msg, ["|"], []);
|
||||
if (llList2String(data, 1) == "[SAVE]")
|
||||
{
|
||||
llRegionSay(comm_channel, "PROPSEARCH");
|
||||
}
|
||||
}
|
||||
else if (num == 90065)
|
||||
{
|
||||
remove_props_by_sitter(msg, FALSE);
|
||||
remove_worn(id);
|
||||
integer index = llListFindList(SITTERS, [id]);
|
||||
if (~index)
|
||||
{
|
||||
SITTERS = llListReplaceList(SITTERS, [NULL_KEY], index, index);
|
||||
}
|
||||
}
|
||||
else if (num == 90030)
|
||||
{
|
||||
remove_props_by_sitter(msg, FALSE);
|
||||
remove_props_by_sitter((string)id, FALSE);
|
||||
SITTERS = llListReplaceList(SITTERS, [NULL_KEY], (integer)msg, (integer)msg);
|
||||
SITTERS = llListReplaceList(SITTERS, [NULL_KEY], (integer)((string)id), (integer)((string)id));
|
||||
}
|
||||
else if (num == 90070)
|
||||
{
|
||||
SITTERS = llListReplaceList(SITTERS, [id], (integer)msg, (integer)msg);
|
||||
}
|
||||
else if (num == 90171 || num == 90173)
|
||||
{
|
||||
integer sitter;
|
||||
if (num == 90171)
|
||||
{
|
||||
sitter = (integer)msg;
|
||||
prop_triggers += [llList2String(SITTER_POSES, sitter)];
|
||||
}
|
||||
else
|
||||
{
|
||||
sitter = 0;
|
||||
SITTER_POSES = ["0|" + msg];
|
||||
prop_triggers += "0|" + msg;
|
||||
}
|
||||
prop_types += 0;
|
||||
prop_objects += (string)id;
|
||||
string prop_group = (string)sitter + "|G1";
|
||||
prop_groups += prop_group;
|
||||
if (llListFindList(sequential_prop_groups, [prop_group]) == -1)
|
||||
{
|
||||
sequential_prop_groups += prop_group;
|
||||
}
|
||||
prop_positions += <0,0,1>;
|
||||
prop_rotations += <0,0,0>;
|
||||
prop_points += "";
|
||||
rez_prop(llGetListLength(prop_triggers) - 1);
|
||||
string text = "PROP added: '" + (string)id + "' to '" + element(llList2String(SITTER_POSES, sitter), 1) + "'";
|
||||
if (llGetListLength(SITTERS) > 1)
|
||||
{
|
||||
text += " for SITTER " + (string)sitter;
|
||||
}
|
||||
llSay(0, text);
|
||||
llSay(0, "Position your prop and click [SAVE].");
|
||||
}
|
||||
else if (num == 90020 && (string)id == llGetScriptName())
|
||||
{
|
||||
integer i;
|
||||
for (; i < llGetListLength(prop_triggers); i++)
|
||||
{
|
||||
if (llSubStringIndex(llList2String(prop_triggers, i), msg + "|") == 0)
|
||||
{
|
||||
string type = (string)llList2Integer(prop_types, i);
|
||||
if (type == "0")
|
||||
{
|
||||
type = "";
|
||||
}
|
||||
Readout_Say("PROP" + type + " " + llDumpList2String([element(llList2String(prop_triggers, i), 1), llList2String(prop_objects, i), element(llList2String(prop_groups, i), 1), llList2String(prop_positions, i), llList2String(prop_rotations, i), llList2String(prop_points, i)], "|"));
|
||||
}
|
||||
}
|
||||
llMessageLinked(LINK_THIS, 90021, msg, llGetScriptName());
|
||||
}
|
||||
}
|
||||
}
|
||||
changed(integer change)
|
||||
{
|
||||
if (change & CHANGED_INVENTORY)
|
||||
{
|
||||
if (llGetInventoryKey(notecard_name) != notecard_key)
|
||||
{
|
||||
remove_all_props();
|
||||
llResetScript();
|
||||
}
|
||||
else if (get_number_of_scripts() != llGetListLength(SITTERS))
|
||||
{
|
||||
init_sitters();
|
||||
}
|
||||
}
|
||||
else if (change & CHANGED_LINK)
|
||||
{
|
||||
if (llGetAgentSize(llGetLinkKey(llGetNumberOfPrims())) == ZERO_VECTOR)
|
||||
{
|
||||
HAVENTNAGGED = TRUE;
|
||||
if (llGetInventoryType(main_script) == INVENTORY_SCRIPT)
|
||||
{
|
||||
remove_all_props();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
listen(integer channel, string name, key id, string message)
|
||||
{
|
||||
list data = llParseStringKeepNulls(message, ["|"], []);
|
||||
if (llList2String(data, 0) == "SAVEPROP")
|
||||
{
|
||||
integer index = (integer)llList2String(data, 1);
|
||||
if (index >= 0 && index < llGetListLength(prop_triggers))
|
||||
{
|
||||
if (llList2Vector(llGetObjectDetails(id, [OBJECT_POS]), 0) != ZERO_VECTOR)
|
||||
{
|
||||
list details = [OBJECT_POS, OBJECT_ROT];
|
||||
rotation f = llList2Rot(details = llGetObjectDetails(llGetKey(), details) + llGetObjectDetails(id, details), 1);
|
||||
vector target_rot = llRot2Euler(llList2Rot(details, 3) / f) * RAD_TO_DEG;
|
||||
vector target_pos = (llList2Vector(details, 2) - llList2Vector(details, 0)) / f;
|
||||
prop_positions = llListReplaceList(prop_positions, [target_pos], index, index);
|
||||
prop_rotations = llListReplaceList(prop_rotations, [target_rot], index, index);
|
||||
string type = llList2String(prop_types, index);
|
||||
if (type == "0")
|
||||
{
|
||||
type = "";
|
||||
}
|
||||
string text = "PROP Saved to memory, SITTER " + element(llList2String(prop_triggers, index), 0) + ": PROP" + type + " " + element(llList2String(prop_triggers, index), 1) + "|" + name + "|" + element(llList2String(prop_groups, index), 1) + "|" + (string)target_pos + "|" + (string)target_rot + "|" + llList2String(prop_points, index);
|
||||
llSay(0, text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Out(0, "Error, cannot find prop: " + name);
|
||||
}
|
||||
}
|
||||
else if (llList2String(data, 0) == "ATTACHED" || llList2String(data, 0) == "DETACHED" || llList2String(data, 0) == "REZ" || llList2String(data, 0) == "DEREZ")
|
||||
{
|
||||
integer prop_index = (integer)llList2String(data, 1);
|
||||
integer sitter = (integer)llList2String(llParseStringKeepNulls(llList2String(prop_triggers, prop_index), ["|"], []), 0);
|
||||
key sitter_key = llList2Key(SITTERS, sitter);
|
||||
if (sitter_key != NULL_KEY && llList2String(data, 0) == "REZ" && llList2Integer(prop_types, prop_index) == 1)
|
||||
{
|
||||
llSay(comm_channel, "ATTACHTO|" + (string)sitter_key + "|" + (string)id);
|
||||
}
|
||||
llMessageLinked(LINK_SET, 90500, llDumpList2String([llList2String(data, 0), llList2String(prop_triggers, prop_index), llList2String(prop_objects, prop_index), llList2String(llParseStringKeepNulls(llList2String(prop_groups, prop_index), ["|"], []), 1), id], "|"), sitter_key);
|
||||
}
|
||||
else if (llList2String(data, 0) == "NAG" && HAVENTNAGGED && (!llGetAttached()))
|
||||
{
|
||||
llRegionSayTo(llGetOwner(), 0, "To enable auto-attachments, please enable the experience '" + llList2String(data, 1) + "' by Code Violet in 'About Land'.");
|
||||
HAVENTNAGGED = FALSE;
|
||||
}
|
||||
}
|
||||
dataserver(key query_id, string data)
|
||||
{
|
||||
if (query_id == notecard_query)
|
||||
{
|
||||
if (data == EOF)
|
||||
{
|
||||
Out(0, (string)llGetListLength(prop_triggers) + " Props Ready, Mem=" + (string)llGetFreeMemory());
|
||||
}
|
||||
else
|
||||
{
|
||||
data = llGetSubString(data, llSubStringIndex(data, "◆") + 1, -1);
|
||||
data = llStringTrim(data, STRING_TRIM);
|
||||
string command = llGetSubString(data, 0, llSubStringIndex(data, " ") - 1);
|
||||
list parts = llParseStringKeepNulls(llGetSubString(data, llSubStringIndex(data, " ") + 1, -1), [" | ", " |", "| ", "|"], []);
|
||||
if (command == "SITTER")
|
||||
{
|
||||
notecard_section = (integer)llList2String(parts, 0);
|
||||
}
|
||||
else if (llGetSubString(command, 0, 3) == "PROP")
|
||||
{
|
||||
if (llGetListLength(prop_triggers) == 100)
|
||||
{
|
||||
Out(0, "Max props is 100, could not add prop!"); // the real limit is less than this due to memory running out first :)
|
||||
}
|
||||
else
|
||||
{
|
||||
integer prop_type;
|
||||
if (command == "PROP1")
|
||||
{
|
||||
prop_type = 1;
|
||||
}
|
||||
else if (command == "PROP2")
|
||||
{
|
||||
prop_type = 2;
|
||||
}
|
||||
else if (command == "PROP3")
|
||||
{
|
||||
prop_type = 3;
|
||||
}
|
||||
prop_triggers += [(string)notecard_section + "|" + llList2String(parts, 0)];
|
||||
prop_types += prop_type;
|
||||
prop_objects += llList2String(parts, 1);
|
||||
string prop_group = (string)notecard_section + "|" + llList2String(parts, 2);
|
||||
prop_groups += prop_group;
|
||||
if (llListFindList(sequential_prop_groups, [prop_group]) == -1)
|
||||
{
|
||||
sequential_prop_groups += prop_group;
|
||||
}
|
||||
prop_positions += (vector)llList2String(parts, 3);
|
||||
prop_rotations += (vector)llList2String(parts, 4);
|
||||
prop_points += llList2String(parts, 5);
|
||||
}
|
||||
}
|
||||
else if (command == "WARN")
|
||||
{
|
||||
WARN = (integer)llList2String(parts, 0);
|
||||
}
|
||||
notecard_query = llGetNotecardLine(notecard_name, notecard_line += 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
// Shared props with BUTTON (alpha) v0.01a
|
||||
//
|
||||
// Allows props to be rezzed by button. They won't derez when sitters "swap" or
|
||||
// if only one avatar stands up. Requires [AV]prop script from AVsitter2
|
||||
// box 2.1-09.01 or later. Shared props should use PROP3 in the AVpos notecard
|
||||
// (a special prop type specifically for shared props).
|
||||
//
|
||||
// example use:
|
||||
//
|
||||
// BUTTON myprop|555 <--- rez the prop
|
||||
// BUTTON [CLEAR]|555 <--- clear all props
|
||||
// BUTTON remprop_myprop|555 <--- derez the prop
|
||||
// PROP3 myprop|object|0|<0,0,0><0,0,0> <--- define the prop (in any SITTER)
|
||||
|
||||
default
|
||||
{
|
||||
link_message(integer sender, integer num, string msg, key id)
|
||||
{
|
||||
if (num != 555) return
|
||||
|
||||
llMessageLinked(LINK_THIS, 90220, "remprop_" + msg, NULL_KEY); // remove the prop
|
||||
llMessageLinked(LINK_THIS, 90220, msg, NULL_KEY); // rez the prop
|
||||
llMessageLinked(LINK_THIS, 90005, "", id); // give back the menu
|
||||
}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
// Shared prop script (alpha) v0.04a
|
||||
//
|
||||
// - Allows props to be "shared" i.e. props will rez while any one of a number
|
||||
// of POSE/SYNC are playing for any avatar.
|
||||
// - Also replaces the need for the "Rez Same Prop for Several Poses" script.
|
||||
// - Requires [AV]prop script from AVsitter2 box 2.1-09 or later.
|
||||
// - Shared props should use PROP3 in the AVpos notecard (a special prop type
|
||||
// specifically for shared props).
|
||||
// - Shared props can be set up in SITTER 0 section of the AVpos notecard in a
|
||||
// regular setup prim, or in a dedicated rezzer prim.
|
||||
// - Props for a specific sitter can use PROP, PROP1 or PROP2.
|
||||
// - All props referenced by this script should be named different from pose
|
||||
// names (unlike basic props, which do have names that match poses).
|
||||
//
|
||||
// - SITTER_SITTER_PROPS_N_POSES is your list of SITTER#, PROP names, and
|
||||
// POSE/SYNC names the props are for.
|
||||
// e.g: 0, "weights", "stand1,stand2"
|
||||
// - SITTER with -1 indicates the prop is for all sitters (i.e. shared prop,
|
||||
// that should use PROP3 in the AVpos notecard).
|
||||
// e.g: -1,"prop1", "sit1,sit2,sit3"
|
||||
//
|
||||
// - "*" for POSE name indicates the prop should rez for all poses.
|
||||
|
||||
list SITTER_PROPS_N_POSES = [
|
||||
-1, "prop1", "sit1,sit2,sit3",
|
||||
-1, "prop2", "sit4,sync2",
|
||||
-1, "prop3", "sync1,sync2",
|
||||
0, "hat", "*",
|
||||
0, "weights", "weights1,weights2",
|
||||
1, "weights", "weights1,weights2"
|
||||
];
|
||||
|
||||
|
||||
list SITTER_PRIMS; // which prims have AVsitter setups
|
||||
list SITTER_POSES_BY_PRIM; // which poses are playing for each sitter in each prim
|
||||
list SITTERS_BY_PRIM; // which sitters are occupied in each setup prim
|
||||
list REZZED; // which props are rezzed, for which avatars
|
||||
integer ANY_SITTERS; // if avatars are sitting
|
||||
|
||||
rez_derez()
|
||||
{
|
||||
integer i;
|
||||
for (; i < llGetListLength(SITTER_PROPS_N_POSES); i += 3)
|
||||
{
|
||||
integer wasRezzed = llList2Integer(REZZED, i);
|
||||
integer forSitter = llList2Integer(SITTER_PROPS_N_POSES, i);
|
||||
list poses = llParseString2List(llList2String(SITTER_PROPS_N_POSES, i + 2), [","], []);
|
||||
|
||||
integer j;
|
||||
for (; j < llGetListLength(poses); j++)
|
||||
{
|
||||
integer k;
|
||||
for (; k < llGetListLength(SITTER_PRIMS); k++)
|
||||
{
|
||||
list SITTER_POSES_IN_PRIM = llParseStringKeepNulls(llList2String(SITTER_POSES_BY_PRIM, k), ["|"], []);
|
||||
|
||||
integer found = llListFindList(SITTER_POSES_IN_PRIM, [llList2String(poses, j)]);
|
||||
if (~found || llList2String(poses, j) == "*")
|
||||
{
|
||||
list SITTERS_IN_PRIM = llParseStringKeepNulls(llList2String(SITTERS_BY_PRIM, k), ["|"], []);
|
||||
|
||||
integer l = found;
|
||||
for (; l < llGetListLength(SITTERS_IN_PRIM); l++)
|
||||
{
|
||||
if (forSitter == -1 || forSitter == l)
|
||||
{
|
||||
if ((llList2String(SITTER_POSES_IN_PRIM, l) == llList2String(poses, j) || llList2String(poses, j) == "*") && llList2String(SITTERS_IN_PRIM, l) != "")
|
||||
{
|
||||
if (!llList2Integer(REZZED, i))
|
||||
{
|
||||
string uuid;
|
||||
if (forSitter == l)
|
||||
{
|
||||
uuid = llList2String(SITTERS_IN_PRIM,l);
|
||||
}
|
||||
|
||||
// llOwnerSay("===REZ====" + llList2String(SITTER_PROPS_N_POSES, i + 1) + "for uuid:" + uuid);
|
||||
|
||||
// rez our prop
|
||||
llMessageLinked(LINK_THIS, 90220, llList2String(SITTER_PROPS_N_POSES, i + 1), uuid);
|
||||
|
||||
REZZED = llListReplaceList(REZZED, [TRUE, uuid], i, i + 1);
|
||||
}
|
||||
jump done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wasRezzed)
|
||||
{
|
||||
string uuid;
|
||||
if (~llList2Integer(SITTER_PROPS_N_POSES, i))
|
||||
{
|
||||
uuid = llList2String(SITTER_PROPS_N_POSES, i);
|
||||
}
|
||||
|
||||
// llOwnerSay("===DEREZ====" + llList2String(SITTER_PROPS_N_POSES, i + 1) + "for uuid:" + uuid);
|
||||
|
||||
// remove our prop
|
||||
llMessageLinked(LINK_THIS, 90220, "remprop_" + llList2String(SITTER_PROPS_N_POSES, i + 1), uuid);
|
||||
|
||||
REZZED = llListReplaceList(REZZED, [FALSE], i, i);
|
||||
}
|
||||
@done;
|
||||
}
|
||||
}
|
||||
|
||||
list fill_array(integer x)
|
||||
{
|
||||
list array;
|
||||
|
||||
integer i;
|
||||
for (; i < x; i++)
|
||||
{
|
||||
array += "";
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
default
|
||||
{
|
||||
state_entry()
|
||||
{
|
||||
REZZED = fill_array(llGetListLength(SITTER_PROPS_N_POSES));
|
||||
}
|
||||
|
||||
link_message(integer sender, integer num, string msg, key id)
|
||||
{
|
||||
// if props were cleared with a BUTTON
|
||||
if (msg == "[CLEAR]")
|
||||
{
|
||||
REZZED = fill_array(llGetListLength(SITTER_PROPS_N_POSES));
|
||||
}
|
||||
// pose played
|
||||
else if (num == 90045)
|
||||
{
|
||||
list data = llParseStringKeepNulls(msg, ["|"], []);
|
||||
integer SITTER_NUMBER = (integer)llList2String(data, 0);
|
||||
string POSE_NAME = llList2String(data, 1);
|
||||
list SITTERS_IN_PRIM = llParseStringKeepNulls(llList2String(data, 4), ["@"], []);
|
||||
list LAST_SITTERS_IN_PRIM;
|
||||
list SITTER_POSES_IN_PRIM;
|
||||
|
||||
integer index = llListFindList(SITTER_PRIMS, [sender]);
|
||||
if (~index)
|
||||
{
|
||||
SITTER_POSES_IN_PRIM = llParseStringKeepNulls(llList2String(SITTER_POSES_BY_PRIM, index), ["|"], []);
|
||||
SITTER_PRIMS = llDeleteSubList(SITTER_PRIMS, index, index);
|
||||
SITTER_POSES_BY_PRIM = llDeleteSubList(SITTER_POSES_BY_PRIM, index, index);
|
||||
LAST_SITTERS_IN_PRIM = llParseStringKeepNulls(llList2String(SITTERS_BY_PRIM, index), ["|"], []);
|
||||
SITTERS_BY_PRIM = llDeleteSubList(SITTERS_BY_PRIM, index, index);
|
||||
|
||||
// if the sitters have swapped, consider any props for the changed sitters derezzed
|
||||
integer i;
|
||||
for (; i < llGetListLength(LAST_SITTERS_IN_PRIM); i++)
|
||||
{
|
||||
if (llList2String(SITTERS_IN_PRIM, i) != llList2String(LAST_SITTERS_IN_PRIM, i))
|
||||
{
|
||||
integer j;
|
||||
for (; j < llGetListLength(SITTER_PROPS_N_POSES); j += 3)
|
||||
{
|
||||
if (llList2Integer(SITTER_PROPS_N_POSES, j) == i)
|
||||
{
|
||||
REZZED = llListReplaceList(REZZED, [FALSE, ""], j, j + 1);
|
||||
// llOwnerSay("rezzed:" + llList2CSV(REZZED));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SITTER_POSES_IN_PRIM = fill_array(llGetListLength(SITTERS_IN_PRIM));
|
||||
}
|
||||
|
||||
SITTER_POSES_IN_PRIM = llListReplaceList(SITTER_POSES_IN_PRIM, [POSE_NAME], SITTER_NUMBER, SITTER_NUMBER);
|
||||
SITTER_PRIMS += sender;
|
||||
SITTER_POSES_BY_PRIM += llDumpList2String(SITTER_POSES_IN_PRIM, "|");
|
||||
SITTERS_BY_PRIM += llDumpList2String(SITTERS_IN_PRIM, "|");
|
||||
|
||||
rez_derez();
|
||||
}
|
||||
// sitter stands
|
||||
else if (num == 90065)
|
||||
{
|
||||
integer index = llListFindList(SITTER_PRIMS, [sender]);
|
||||
if (~index)
|
||||
{
|
||||
list SITTER_POSES_IN_PRIM = llParseStringKeepNulls(llList2String(SITTER_POSES_BY_PRIM, index), ["|"], []);
|
||||
SITTER_POSES_IN_PRIM = llListReplaceList(SITTER_POSES_IN_PRIM, [""], (integer)msg, (integer)msg);
|
||||
SITTER_POSES_BY_PRIM = llListReplaceList(SITTER_POSES_BY_PRIM, [llDumpList2String(SITTER_POSES_IN_PRIM, "|")], index, index);
|
||||
list SITTERS_IN_PRIM = llParseStringKeepNulls(llList2String(SITTERS_BY_PRIM, index), ["|"], []);
|
||||
SITTERS_IN_PRIM = llListReplaceList(SITTERS_IN_PRIM, [""], (integer)msg, (integer)msg);
|
||||
SITTERS_BY_PRIM = llListReplaceList(SITTERS_BY_PRIM, [llDumpList2String(SITTERS_IN_PRIM, "|")], index, index);
|
||||
|
||||
rez_derez();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
changed(integer change)
|
||||
{
|
||||
if (change & CHANGED_LINK)
|
||||
{
|
||||
integer IS_SITTER;
|
||||
|
||||
// someone is sitting
|
||||
if (llGetAgentSize(llGetLinkKey(llGetNumberOfPrims())))
|
||||
{
|
||||
IS_SITTER = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SITTER_PRIMS = [];
|
||||
SITTER_POSES_BY_PRIM = [];
|
||||
SITTERS_BY_PRIM = [];
|
||||
}
|
||||
|
||||
if (IS_SITTER != ANY_SITTERS)
|
||||
{
|
||||
ANY_SITTERS = IS_SITTER;
|
||||
|
||||
rez_derez();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue