From 48d171ca34e9fdbbd6ddd7a30b3bccd35fe706fd Mon Sep 17 00:00:00 2001 From: iDunnoDev Date: Sat, 27 Sep 2025 10:48:07 +0100 Subject: [PATCH] Initial Upload --- Cawfee/awfullyhotcawfeepahot.lsl | 161 +++++++++++ Coller/Control.lsl | 28 ++ Coller/Obey.lsl | 72 +++++ Rose/Forever.lsl | 71 +++++ Rose/MenuGen.lsl | 297 ++++++++++++++++++++ SoundBoardAndSpeaker/ButtonControl.lsl | 17 ++ SoundBoardAndSpeaker/ButtonControlLoop.lsl | 17 ++ SoundBoardAndSpeaker/SpeakerControl.lsl | 24 ++ SoundBoardAndSpeaker/SpeakerMainControl.lsl | 109 +++++++ Throne/MenuGen.lsl | 297 ++++++++++++++++++++ Throne/ThroneDefault.lsl | 188 +++++++++++++ 11 files changed, 1281 insertions(+) create mode 100644 Cawfee/awfullyhotcawfeepahot.lsl create mode 100644 Coller/Control.lsl create mode 100644 Coller/Obey.lsl create mode 100644 Rose/Forever.lsl create mode 100644 Rose/MenuGen.lsl create mode 100644 SoundBoardAndSpeaker/ButtonControl.lsl create mode 100644 SoundBoardAndSpeaker/ButtonControlLoop.lsl create mode 100644 SoundBoardAndSpeaker/SpeakerControl.lsl create mode 100644 SoundBoardAndSpeaker/SpeakerMainControl.lsl create mode 100644 Throne/MenuGen.lsl create mode 100644 Throne/ThroneDefault.lsl diff --git a/Cawfee/awfullyhotcawfeepahot.lsl b/Cawfee/awfullyhotcawfeepahot.lsl new file mode 100644 index 0000000..9de422d --- /dev/null +++ b/Cawfee/awfullyhotcawfeepahot.lsl @@ -0,0 +1,161 @@ +integer actual_seconds_passed = 15; // Counter for Seconds since last sip was taken, once it passes the minimum another can and this is reset +integer minimum_seconds_needed = 20; // Number of Seconds before a Sip can be take +float act_frequency = 0.3; // Frequency % of Sip to add RNG + +integer full_level = 100; // Full size of drink, not really used +integer current_drink_level = 0; // Counter for the current drink value to help calc the alpha changes +list cawfeeLevelFaceInts = [4, 3, 2, 1]; // Array of face Integers on the mesh model + +float animation_mid_point = 1; // Number of seconds to sleep during the animation to help it line up +string idle_anim = "cawfeeidle"; // Animation used for idle +string action_anim = "cawfeeswig"; // Animation used for swiggin +list no_cawfee_anims = ["cawfeenocawfeeA", "cawfeenocawfeeB"]; // Animation used for the worst outcome +list cawfee_reloaded_anims = ["cawfeerenewedA", "cawfeerenewedB"]; // +integer NO_CAWFEE = 0; // int for no cawfee, really its to check if we already did the no cawfee anim +integer NO_CAWFEE_WHICH = 0; // int to store which animation set is currently playing for the no cawfee + +integer freeze_logic = 0; // 1 TRUE, 0 FALSE, Freezes the alpha script checks + +integer sip_multiplier = 20; // Bigger number for bigger sips +string sip_sfx = "SipSFX"; // SFX used for sippin +float sip_sound_vol = 0.0; // Volume for Sip SFX +integer sip_do_sound = 0; // 1 TRUE, 0 FALSE, toggle for disabling the annoying sound + +list particle_settings = [ + PSYS_PART_MAX_AGE,1.50, + PSYS_PART_FLAGS, 259, + PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>, + PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>, + PSYS_PART_START_SCALE,<0.15062, 0.15062, 0.00000>, + PSYS_PART_END_SCALE,<0.77423, 1.21800, 0.00000>, + PSYS_SRC_PATTERN, 2, + PSYS_SRC_BURST_RATE,0.00, + PSYS_SRC_BURST_PART_COUNT,3, + PSYS_SRC_BURST_RADIUS,0.00, + PSYS_SRC_BURST_SPEED_MIN,0.07, + PSYS_SRC_BURST_SPEED_MAX,0.35, + PSYS_SRC_ANGLE_BEGIN, 1.65, + PSYS_SRC_ANGLE_END, 0.00, + PSYS_SRC_MAX_AGE, 10.0, + PSYS_SRC_TEXTURE, "006d9758-81da-38a9-9be3-b6c941cae931", + PSYS_PART_START_ALPHA, 0.40, + PSYS_PART_END_ALPHA, 0.00, + PSYS_SRC_ACCEL, <0.00, 0.00, 1.14> + ]; + +default +{ + state_entry() { + llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); + llSetTimerEvent(1); + llStartAnimation(idle_anim); + } + + on_rez(integer param) { + llResetScript(); + current_drink_level = 0; + actual_seconds_passed = 0; + + llSetLinkAlpha(LINK_ALL_OTHERS, 1.0, ALL_SIDES); // Reset alphas on touch + } + + attach(key id) + { + integer perm = llGetPermissions(); + + if (id != NULL_KEY) { + if (!(perm & PERMISSION_TRIGGER_ANIMATION)) { + llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); + } + llStartAnimation(idle_anim); + } else { + llStopAnimation(idle_anim); + llStopAnimation(action_anim); + integer i = 0; + integer total_no_cawf_anims = llGetListLength(no_cawfee_anims); + for (i = 0; i < total_no_cawf_anims; ++i) { + llStopAnimation(llList2String(no_cawfee_anims, i)); + llStopAnimation(llList2String(cawfee_reloaded_anims, i)); + } + current_drink_level = 0; + actual_seconds_passed = 0; + llSetLinkAlpha(LINK_ALL_OTHERS, 1.0, ALL_SIDES); // Reset alphas on touch + + } + } + + moving_start() + { + if (NO_CAWFEE == 1) { + NO_CAWFEE = 0; + llStopAnimation(llList2String(cawfee_reloaded_anims, NO_CAWFEE_WHICH)); + llStopAnimation(llList2String(no_cawfee_anims, NO_CAWFEE_WHICH)); + actual_seconds_passed = -30; + } + } + + touch(integer num_detected) { + current_drink_level = 0; + actual_seconds_passed = 0; + llParticleSystem(particle_settings); + + llSleep(animation_mid_point); // Sleep so particle effect can start + llSetLinkAlpha(LINK_ALL_OTHERS, 1.0, ALL_SIDES); // Reset alphas on touch + + if (NO_CAWFEE == 1) { + NO_CAWFEE = 0; + llSleep(10); + llStartAnimation(llList2String(cawfee_reloaded_anims, NO_CAWFEE_WHICH)); + llSleep(2); + llStopAnimation(llList2String(no_cawfee_anims, NO_CAWFEE_WHICH)); + } + + } + + timer() { + if (actual_seconds_passed >= minimum_seconds_needed) { + if ((current_drink_level < full_level)) { + float roll_dem_bones = llFrand(1.0); + if (roll_dem_bones <= act_frequency) { + llStartAnimation(action_anim); + actual_seconds_passed = 0; + + if ((current_drink_level < full_level) && (freeze_logic != 1)) { + integer sip_size = llRound((llFrand(1.0) * sip_multiplier)); + current_drink_level += sip_size; + + llSleep(animation_mid_point); // Sleep to stop alpha going before the animation has touched face like + if (sip_do_sound == 1) { + llPlaySound(sip_sfx, sip_sound_vol); + } + if (current_drink_level >= 15 && current_drink_level < 35) { + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 0)); + } else if (current_drink_level >= 35 && current_drink_level < 75) { + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 0)); + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 1)); + } else if (current_drink_level >= 75 && current_drink_level < 100) { + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 0)); + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 1)); + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 2)); + } else if (current_drink_level >= 100) { + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 0)); + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 1)); + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 2)); + llSetLinkAlpha(LINK_ALL_OTHERS, 0.0, llList2Integer(cawfeeLevelFaceInts, 3)); + } + } + } else { + ++actual_seconds_passed; + } + } else { + if (NO_CAWFEE != 1) { + NO_CAWFEE_WHICH = ((llRound(2.0 - llFrand(1))) - 1); + llStartAnimation(llList2String(no_cawfee_anims, NO_CAWFEE_WHICH)); + NO_CAWFEE = 1; + } + } + } else { + ++actual_seconds_passed; + } + } +} diff --git a/Coller/Control.lsl b/Coller/Control.lsl new file mode 100644 index 0000000..44d21d2 --- /dev/null +++ b/Coller/Control.lsl @@ -0,0 +1,28 @@ +integer listen_chan = 1347453612; +integer toggle_state = 0; + +default +{ + state_entry() + { + + } + + touch_start(integer total_number) + { + if (toggle_state == 0) { + llRegionSay(listen_chan, "obey"); + } else if (toggle_state == 1) { + llRegionSay(listen_chan, "release"); + } + } + + touch_end(integer total_number) { + if (toggle_state == 0) { + llRegionSay(listen_chan, "obey_rel"); + toggle_state = 1; + } else if (toggle_state == 1) { + toggle_state = 0; + } + } +} diff --git a/Coller/Obey.lsl b/Coller/Obey.lsl new file mode 100644 index 0000000..5b482c8 --- /dev/null +++ b/Coller/Obey.lsl @@ -0,0 +1,72 @@ +integer listen_chan = 1347453612; +integer listenHandle; +float sfx_vol = 1.0; +integer timer_toggle = 0; +float blink_timer = 0.1; +integer blinker_face = 2; +vector blink_working_a = <1.000, 0.255, 0.212>; +vector blink_working_b = <0.067, 0.067, 0.067>; +vector blink_live = <1.000, 0.255, 0.212>; +vector blink_free = <0.180, 0.800, 0.251>; + +default +{ + state_entry() + { + listenHandle = llListen(listen_chan, "", NULL_KEY, ""); + integer perm = llGetPermissions(); + llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS); + } + + on_rez(integer start_param) { + llResetScript(); + } + + listen(integer channel, string name, key id, string message) + { + integer perm = llGetPermissions(); + if (message == "obey") { + llSetTimerEvent(blink_timer); + llOwnerSay("Obey"); + llLoopSound("leccy", sfx_vol); + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStartAnimation("zap_hold"); + } + if(PERMISSION_TAKE_CONTROLS & perm) { + llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT | + CONTROL_UP | CONTROL_DOWN | CONTROL_LBUTTON | CONTROL_ML_LBUTTON, TRUE, FALSE); + } + } else if (message == "obey_rel") { + llOwnerSay("Obey!!"); + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStartAnimation("zap_release"); + llStopAnimation("zap_hold"); + } + llSetTimerEvent(0.0); + llSetColor(blink_live, blinker_face); + llStopSound(); + } else if (message == "release") { + llOwnerSay("Release"); + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStopAnimation("zap_hold"); + llStopAnimation("zap_release"); + } + if(PERMISSION_TAKE_CONTROLS & perm) { + llTakeControls(CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_LEFT | CONTROL_ROT_RIGHT | + CONTROL_UP | CONTROL_DOWN | CONTROL_LBUTTON | CONTROL_ML_LBUTTON, TRUE, TRUE); + } + llSetColor(blink_free, blinker_face); + } + } + + timer() { + if (timer_toggle == 0) { + llSetColor(blink_working_a, blinker_face); + timer_toggle = 1; + } else if (timer_toggle == 1) { + llSetColor(blink_working_b, blinker_face); + timer_toggle = 0; + } + } +} + diff --git a/Rose/Forever.lsl b/Rose/Forever.lsl new file mode 100644 index 0000000..3aae3dd --- /dev/null +++ b/Rose/Forever.lsl @@ -0,0 +1,71 @@ +string offer_anim = "offerrose"; +string child_rose = "BlueRose"; +integer offering = 0; + +// Link Commands +integer LINK_MENU_DISPLAY = 300; +integer LINK_MENU_RETURN = 320; +integer LINK_MENU_TIMEOUT = 330; + + +DisplayMenu(key id) { + string menuDescripter = "rosemenu"; + string menuNavigate = "FALSE"; + string menuText = "Your choice?"; + string menuButtons = "Offer"; // The buttons, each button separated by a '~'. + + llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, menuDescripter+"|"+menuNavigate+"|"+menuText+"|"+ menuButtons, id); +} + +default +{ + state_entry() { + llSetAlpha(0, ALL_SIDES); + key av = llGetOwner(); + llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION | PERMISSION_ATTACH); + DisplayMenu(av); + } + + on_rez(integer start_param) { + llResetScript(); + } + + touch_end(integer total_number) { + if (offering == 1) { + llSetAlpha(0, ALL_SIDES); + llStopAnimation(offer_anim); + llGiveInventory(llDetectedKey(0), child_rose); + offering = 0; + integer perm = llGetPermissions(); + if(perm & PERMISSION_ATTACH) { + llDetachFromAvatar(); + } + } + } + + link_message(integer intSenderNum, integer num, string message, key id) { + if (num == LINK_MENU_RETURN) { + list returnMenu = llParseString2List(message, ["|"], []); + string menuDescriptor = llList2String(returnMenu,0); + + if (menuDescriptor == "rosemenu") { + string item = llList2String(returnMenu,1); + if (item == "Offer") { + integer perm = llGetPermissions(); + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStartAnimation(offer_anim); + llSleep(1.0); + llSetAlpha(1, ALL_SIDES); + llSleep(1.0); + offering = 1; + } + } + } + } else if (num == LINK_MENU_TIMEOUT) { + if (message == "rosemenu") { + key av = llGetOwner(); + DisplayMenu(av); + } + } + } +} diff --git a/Rose/MenuGen.lsl b/Rose/MenuGen.lsl new file mode 100644 index 0000000..5a97760 --- /dev/null +++ b/Rose/MenuGen.lsl @@ -0,0 +1,297 @@ +// ******************************************************************** +// +// Menu Display Script +// +// Menu command format +// string = menuidentifier | display navigate? TRUE/FALSE | menuMaintitle~subtitle1~subtitle2~subtitle3 | button1~button2~button3 {| fixedbutton1~fixedbutton2~fixedbutton3 optional} +// key = menuuser key +// +// Return is in the format +// "menuidentifier | item" +// +// menusDescription [menuchannel, key, menu & parent, return link, nav?, titles, buttons, fixed buttons] +// menusActive [menuchannel, menuhandle, time, page] +// +// by SimonT Quinnell +// +// CHANGES +// 2010/10/14 - Timeout message now gets sent to the prim that called the menu, not LINK_THIS. Also includes menuidentifier +// 2010/11/29 - Fixed Bug in RemoveUser function. Thanks for Virtouse Lilienthal for pointing it out. +// 2010/11/29 - Tidied up a little and removed functions NewMenu and RemoveUser that are only called once +// 2014/04/28 - Clarified licence +// +// NOTE: This script is licenced using the Creative Commons Attribution-Share Alike 3.0 license +// +// ******************************************************************** + + +// ******************************************************************** +// CONSTANTS +// ******************************************************************** + +// Link Commands +integer LINK_MENU_DISPLAY = 300; +integer LINK_MENU_CLOSE = 310; +integer LINK_MENU_RETURN = 320; +integer LINK_MENU_TIMEOUT = 330; + +// Main Menu Details +string BACK = "<<"; +string FOWARD = ">>"; +list MENU_NAVIGATE_BUTTONS = [ " ", "Back", "Exit"]; +float MENU_TIMEOUT_CHECK = 10.0; +integer MENU_TIMEOUT = 120000000; +integer MAX_TEXT = 510; + + +integer STRIDE_DESCRIPTION = 8; +integer STRIDE_ACTIVE = 4; +integer DEBUG = FALSE; + +// ******************************************************************** +// Variables +// ******************************************************************** + +list menusDescription; +list menusActive; + + +// ******************************************************************** +// Functions - General +// ******************************************************************** + +debug(string debug) +{ + if (DEBUG) llSay(DEBUG_CHANNEL,"DEBUG:"+llGetScriptName()+":"+debug+" : Free("+(string)llGetFreeMemory()+")"); +} + + +integer string2Bool (string test) +{ + if (test == "TRUE") return TRUE; + else return FALSE; +} + +// ******************************************************************** +// Functions - Menu Helpers +// ******************************************************************** + +integer NewChannel() +{ // generates unique channel number + integer channel; + + do channel = -(llRound(llFrand(999999)) + 99999); + while (~llListFindList(menusDescription, [channel])); + + return channel; +} + + +string CheckTitleLength(string title) +{ + if (llStringLength(title) > MAX_TEXT) title = llGetSubString(title, 0, MAX_TEXT-1); + + return title; +} + + +list FillMenu(list buttons) +{ //adds empty buttons until the list length is multiple of 3, to max of 12 + integer i; + list listButtons; + + for(i=0;i 24) name = llGetSubString(name, 0, 23); + listButtons = listButtons + [name]; + } + + while (llGetListLength(listButtons) != 3 && llGetListLength(listButtons) != 6 && llGetListLength(listButtons) != 9 && llGetListLength(listButtons) < 12) + { + listButtons = listButtons + [" "]; + } + + buttons = llList2List(listButtons, 9, 11); + buttons = buttons + llList2List(listButtons, 6, 8); + buttons = buttons + llList2List(listButtons, 3, 5); + buttons = buttons + llList2List(listButtons, 0, 2); + + return buttons; +} + +RemoveMenu(integer channel, integer echo) +{ + integer index = llListFindList(menusDescription, [channel]); + + if (index != -1) + { + key menuId = llList2Key(menusDescription, index+1); + string menuDetails = llList2String(menusDescription, index+2); + integer menuLink = llList2Integer(menusDescription, index+3); + menusDescription = llDeleteSubList(menusDescription, index, index + STRIDE_DESCRIPTION - 1); + RemoveListen(channel); + + if (echo) llMessageLinked(menuLink, LINK_MENU_TIMEOUT, menuDetails, menuId); + } +} + +RemoveListen(integer channel) +{ + integer index = llListFindList(menusActive, [channel]); + if (index != -1) + { + llListenRemove(llList2Integer(menusActive, index + 1)); + menusActive = llDeleteSubList(menusActive, index, index + STRIDE_ACTIVE - 1); + } +} + +// ******************************************************************** +// Functions - Menu Main +// ******************************************************************** + +DisplayMenu(key id, integer channel, integer page) +{ + string menuTitle; + list menuSubTitles; + list menuButtonsAll; + list menuButtons; + list menuNavigateButtons; + list menuFixedButtons; + + integer max = 12; + + // Populate values + integer index = llListFindList(menusDescription, [channel]); + menuButtonsAll = llParseString2List(llList2String(menusDescription, index+6), ["~"], []); + if (llList2String(menusDescription, index+7) != "") menuFixedButtons = llParseString2List(llList2String(menusDescription, index+7), ["~"], []); + + // Set up the menu buttons + if (llList2Integer(menusDescription, index+4)) menuNavigateButtons= MENU_NAVIGATE_BUTTONS; + else if (llGetListLength(menuButtonsAll) > (max-llGetListLength(menuFixedButtons))) menuNavigateButtons = [" ", " ", " "]; + + // FIXME: add sanity check for menu page + + max = max - llGetListLength(menuFixedButtons) - llGetListLength(menuNavigateButtons); + integer start = page*max; + integer stop = (page+1)*max - 1; + menuButtons = FillMenu(menuFixedButtons + llList2List(menuButtonsAll, start, stop)); + + // Generate the title + list tempTitle = llParseString2List(llList2String(menusDescription, index+5), ["~"], []); + menuTitle = llList2String(tempTitle,0); + if (llGetListLength(tempTitle) > 1) menuSubTitles = llList2List(tempTitle, 1, -1); + if (llGetListLength(menuSubTitles) > 0) + { + integer i; + for(i=start;i<(stop+1);++i) + { + if (llList2String(menuSubTitles, i) != "") menuTitle += "\n"+llList2String(menuSubTitles, i); + } + } + menuTitle = CheckTitleLength(menuTitle); + + // Add navigate buttons if necessary + if (page > 0) menuNavigateButtons = llListReplaceList(menuNavigateButtons, [BACK], 0, 0); + if (llGetListLength(menuButtonsAll) > (page+1)*max) menuNavigateButtons = llListReplaceList(menuNavigateButtons, [FOWARD], 2, 2); + + // Set up listen and add the row details + integer menuHandle = llListen(channel, "", id, ""); + menusActive = [channel, menuHandle, llGetUnixTime(), page] + menusActive; + + //llSetTimerEvent(MENU_TIMEOUT_CHECK); + + // Display menu + llDialog(id, menuTitle, menuNavigateButtons + menuButtons, channel); +} + + +// ******************************************************************** +// Event Handlers +// ******************************************************************** + +default +{ + listen(integer channel, string name, key id, string message) + { + if (message == BACK) + { + integer index = llListFindList(menusActive, [channel]); + integer page = llList2Integer(menusActive, index+3)-1; + RemoveListen(channel); + DisplayMenu(id, channel, page); + } + else if (message == FOWARD) + { + integer index = llListFindList(menusActive, [channel]); + integer page = llList2Integer(menusActive, index+3)+1; + RemoveListen(channel); + DisplayMenu(id, channel, page); + } + else if (message == " ") + { + integer index = llListFindList(menusActive, [channel]); + integer page = llList2Integer(menusActive, index+3); + RemoveListen(channel); + DisplayMenu(id, channel, page); + } + else + { + integer index = llListFindList(menusDescription, [channel]); + llMessageLinked(llList2Integer(menusDescription, index+3), LINK_MENU_RETURN, llList2String(menusDescription, index+2)+"|"+message, id); + RemoveMenu(channel, FALSE); + } + } + + link_message(integer senderNum, integer num, string message, key id) + { + if (num == LINK_MENU_DISPLAY) + { // Setup New Menu + list temp = llParseString2List(message, ["|"], []); + integer channel = NewChannel(); + + if (llGetListLength(temp) > 2) + { + menusDescription = [channel, id, llList2String(temp, 0), senderNum, string2Bool(llList2String(temp, 1)), llList2String(temp, 2), llList2String(temp, 3), llList2String(temp, 4)] + menusDescription; + + DisplayMenu(id, channel, 0); + } + else llSay (DEBUG_CHANNEL, "ERROR in "+llGetScriptName()+": Dialog Script. Incorrect menu format"); + } + else if (num == LINK_MENU_CLOSE) + { // Will remove all menus that have the user id. + integer index_id = llListFindList(menusDescription, [id]); + + while (~index_id) + { + integer channel = llList2Integer(menusDescription, index_id-1); + RemoveMenu(channel, FALSE); + + // Check for another menu by same user + index_id = llListFindList(menusDescription, [id]); + } + } + } + + timer() + { // Check through timers and close if necessary + integer i; + list toRemove; + integer currentTime = llGetUnixTime(); + integer length = llGetListLength(menusActive); + + for(i=0;i MENU_TIMEOUT) toRemove = [llList2Integer(menusActive, i)] + toRemove; + } + + length = llGetListLength(toRemove); + if (length > 0) + { + for(i=0;i ") + " - message - " + message); + if (llList2String(call_parts, 1) == "loop") { + integer button_index = llListFindList(sound_list, [llList2String(call_parts, 0)]); + if (button_index != -1) { + string loop_sound_uuid = llList2String(sound_list, button_index + 1); + if (llStringLength(loop_sound_uuid) == 36) { + timer_events += [(current_timer_sec), loop_sound_uuid]; + } + } + } + } + + if (llStringLength(sound_uuid) > 0) { + //llOwnerSay("sound UUID - " + sound_uuid); + llSay(speaker_listen_chan, (string) current_speaker + "+" + sound_uuid); + if (current_speaker < number_of_speakers) { + ++current_speaker; + } else { + current_speaker = 1; + } + } + } + + timer() { + integer number_of_items = llGetListLength(timer_events); + integer list_looper = 0; + + for (list_looper = 0; list_looper <= number_of_items; list_looper += 2) { + if (llList2Integer(timer_events, list_looper) == current_timer_sec) { + string sound_uuid = llList2String(timer_events, list_looper + 1); + //llOwnerSay("sound looped UUID - " + sound_uuid); + llSay(speaker_listen_chan, (string) current_speaker + "+" + sound_uuid); + if (current_speaker < number_of_speakers) { + ++current_speaker; + } else { + current_speaker = 1; + } + } + } + + if (current_timer_sec < loop_length) { + list_looper = 0; + ++ current_timer_sec; + } else { + //llOwnerSay("Loop reset - " + llDumpList2String(timer_events, " > ")); + current_timer_sec = 1; + } + + if (reset_count_start > 0) { + integer reset_in = 4 - reset_count_start; + if (reset_in < 0) { + reset_in = 0; + } + llOwnerSay("Resetting in: " + (string) reset_in + "..."); + if (reset_count_start >= 4) { + timer_events = []; + reset_count_start = 0; + llOwnerSay("Loops Reset"); + } else { + ++reset_count_start; + } + } + } +} diff --git a/Throne/MenuGen.lsl b/Throne/MenuGen.lsl new file mode 100644 index 0000000..5a97760 --- /dev/null +++ b/Throne/MenuGen.lsl @@ -0,0 +1,297 @@ +// ******************************************************************** +// +// Menu Display Script +// +// Menu command format +// string = menuidentifier | display navigate? TRUE/FALSE | menuMaintitle~subtitle1~subtitle2~subtitle3 | button1~button2~button3 {| fixedbutton1~fixedbutton2~fixedbutton3 optional} +// key = menuuser key +// +// Return is in the format +// "menuidentifier | item" +// +// menusDescription [menuchannel, key, menu & parent, return link, nav?, titles, buttons, fixed buttons] +// menusActive [menuchannel, menuhandle, time, page] +// +// by SimonT Quinnell +// +// CHANGES +// 2010/10/14 - Timeout message now gets sent to the prim that called the menu, not LINK_THIS. Also includes menuidentifier +// 2010/11/29 - Fixed Bug in RemoveUser function. Thanks for Virtouse Lilienthal for pointing it out. +// 2010/11/29 - Tidied up a little and removed functions NewMenu and RemoveUser that are only called once +// 2014/04/28 - Clarified licence +// +// NOTE: This script is licenced using the Creative Commons Attribution-Share Alike 3.0 license +// +// ******************************************************************** + + +// ******************************************************************** +// CONSTANTS +// ******************************************************************** + +// Link Commands +integer LINK_MENU_DISPLAY = 300; +integer LINK_MENU_CLOSE = 310; +integer LINK_MENU_RETURN = 320; +integer LINK_MENU_TIMEOUT = 330; + +// Main Menu Details +string BACK = "<<"; +string FOWARD = ">>"; +list MENU_NAVIGATE_BUTTONS = [ " ", "Back", "Exit"]; +float MENU_TIMEOUT_CHECK = 10.0; +integer MENU_TIMEOUT = 120000000; +integer MAX_TEXT = 510; + + +integer STRIDE_DESCRIPTION = 8; +integer STRIDE_ACTIVE = 4; +integer DEBUG = FALSE; + +// ******************************************************************** +// Variables +// ******************************************************************** + +list menusDescription; +list menusActive; + + +// ******************************************************************** +// Functions - General +// ******************************************************************** + +debug(string debug) +{ + if (DEBUG) llSay(DEBUG_CHANNEL,"DEBUG:"+llGetScriptName()+":"+debug+" : Free("+(string)llGetFreeMemory()+")"); +} + + +integer string2Bool (string test) +{ + if (test == "TRUE") return TRUE; + else return FALSE; +} + +// ******************************************************************** +// Functions - Menu Helpers +// ******************************************************************** + +integer NewChannel() +{ // generates unique channel number + integer channel; + + do channel = -(llRound(llFrand(999999)) + 99999); + while (~llListFindList(menusDescription, [channel])); + + return channel; +} + + +string CheckTitleLength(string title) +{ + if (llStringLength(title) > MAX_TEXT) title = llGetSubString(title, 0, MAX_TEXT-1); + + return title; +} + + +list FillMenu(list buttons) +{ //adds empty buttons until the list length is multiple of 3, to max of 12 + integer i; + list listButtons; + + for(i=0;i 24) name = llGetSubString(name, 0, 23); + listButtons = listButtons + [name]; + } + + while (llGetListLength(listButtons) != 3 && llGetListLength(listButtons) != 6 && llGetListLength(listButtons) != 9 && llGetListLength(listButtons) < 12) + { + listButtons = listButtons + [" "]; + } + + buttons = llList2List(listButtons, 9, 11); + buttons = buttons + llList2List(listButtons, 6, 8); + buttons = buttons + llList2List(listButtons, 3, 5); + buttons = buttons + llList2List(listButtons, 0, 2); + + return buttons; +} + +RemoveMenu(integer channel, integer echo) +{ + integer index = llListFindList(menusDescription, [channel]); + + if (index != -1) + { + key menuId = llList2Key(menusDescription, index+1); + string menuDetails = llList2String(menusDescription, index+2); + integer menuLink = llList2Integer(menusDescription, index+3); + menusDescription = llDeleteSubList(menusDescription, index, index + STRIDE_DESCRIPTION - 1); + RemoveListen(channel); + + if (echo) llMessageLinked(menuLink, LINK_MENU_TIMEOUT, menuDetails, menuId); + } +} + +RemoveListen(integer channel) +{ + integer index = llListFindList(menusActive, [channel]); + if (index != -1) + { + llListenRemove(llList2Integer(menusActive, index + 1)); + menusActive = llDeleteSubList(menusActive, index, index + STRIDE_ACTIVE - 1); + } +} + +// ******************************************************************** +// Functions - Menu Main +// ******************************************************************** + +DisplayMenu(key id, integer channel, integer page) +{ + string menuTitle; + list menuSubTitles; + list menuButtonsAll; + list menuButtons; + list menuNavigateButtons; + list menuFixedButtons; + + integer max = 12; + + // Populate values + integer index = llListFindList(menusDescription, [channel]); + menuButtonsAll = llParseString2List(llList2String(menusDescription, index+6), ["~"], []); + if (llList2String(menusDescription, index+7) != "") menuFixedButtons = llParseString2List(llList2String(menusDescription, index+7), ["~"], []); + + // Set up the menu buttons + if (llList2Integer(menusDescription, index+4)) menuNavigateButtons= MENU_NAVIGATE_BUTTONS; + else if (llGetListLength(menuButtonsAll) > (max-llGetListLength(menuFixedButtons))) menuNavigateButtons = [" ", " ", " "]; + + // FIXME: add sanity check for menu page + + max = max - llGetListLength(menuFixedButtons) - llGetListLength(menuNavigateButtons); + integer start = page*max; + integer stop = (page+1)*max - 1; + menuButtons = FillMenu(menuFixedButtons + llList2List(menuButtonsAll, start, stop)); + + // Generate the title + list tempTitle = llParseString2List(llList2String(menusDescription, index+5), ["~"], []); + menuTitle = llList2String(tempTitle,0); + if (llGetListLength(tempTitle) > 1) menuSubTitles = llList2List(tempTitle, 1, -1); + if (llGetListLength(menuSubTitles) > 0) + { + integer i; + for(i=start;i<(stop+1);++i) + { + if (llList2String(menuSubTitles, i) != "") menuTitle += "\n"+llList2String(menuSubTitles, i); + } + } + menuTitle = CheckTitleLength(menuTitle); + + // Add navigate buttons if necessary + if (page > 0) menuNavigateButtons = llListReplaceList(menuNavigateButtons, [BACK], 0, 0); + if (llGetListLength(menuButtonsAll) > (page+1)*max) menuNavigateButtons = llListReplaceList(menuNavigateButtons, [FOWARD], 2, 2); + + // Set up listen and add the row details + integer menuHandle = llListen(channel, "", id, ""); + menusActive = [channel, menuHandle, llGetUnixTime(), page] + menusActive; + + //llSetTimerEvent(MENU_TIMEOUT_CHECK); + + // Display menu + llDialog(id, menuTitle, menuNavigateButtons + menuButtons, channel); +} + + +// ******************************************************************** +// Event Handlers +// ******************************************************************** + +default +{ + listen(integer channel, string name, key id, string message) + { + if (message == BACK) + { + integer index = llListFindList(menusActive, [channel]); + integer page = llList2Integer(menusActive, index+3)-1; + RemoveListen(channel); + DisplayMenu(id, channel, page); + } + else if (message == FOWARD) + { + integer index = llListFindList(menusActive, [channel]); + integer page = llList2Integer(menusActive, index+3)+1; + RemoveListen(channel); + DisplayMenu(id, channel, page); + } + else if (message == " ") + { + integer index = llListFindList(menusActive, [channel]); + integer page = llList2Integer(menusActive, index+3); + RemoveListen(channel); + DisplayMenu(id, channel, page); + } + else + { + integer index = llListFindList(menusDescription, [channel]); + llMessageLinked(llList2Integer(menusDescription, index+3), LINK_MENU_RETURN, llList2String(menusDescription, index+2)+"|"+message, id); + RemoveMenu(channel, FALSE); + } + } + + link_message(integer senderNum, integer num, string message, key id) + { + if (num == LINK_MENU_DISPLAY) + { // Setup New Menu + list temp = llParseString2List(message, ["|"], []); + integer channel = NewChannel(); + + if (llGetListLength(temp) > 2) + { + menusDescription = [channel, id, llList2String(temp, 0), senderNum, string2Bool(llList2String(temp, 1)), llList2String(temp, 2), llList2String(temp, 3), llList2String(temp, 4)] + menusDescription; + + DisplayMenu(id, channel, 0); + } + else llSay (DEBUG_CHANNEL, "ERROR in "+llGetScriptName()+": Dialog Script. Incorrect menu format"); + } + else if (num == LINK_MENU_CLOSE) + { // Will remove all menus that have the user id. + integer index_id = llListFindList(menusDescription, [id]); + + while (~index_id) + { + integer channel = llList2Integer(menusDescription, index_id-1); + RemoveMenu(channel, FALSE); + + // Check for another menu by same user + index_id = llListFindList(menusDescription, [id]); + } + } + } + + timer() + { // Check through timers and close if necessary + integer i; + list toRemove; + integer currentTime = llGetUnixTime(); + integer length = llGetListLength(menusActive); + + for(i=0;i MENU_TIMEOUT) toRemove = [llList2Integer(menusActive, i)] + toRemove; + } + + length = llGetListLength(toRemove); + if (length > 0) + { + for(i=0;i; +vector init_pos; +rotation default_rot = <0.000000, 0.000000, -0.707107, 0.707107>; +integer can_ex = 1; +float ex_timer = 20; +float ex_frequency = 0.3; // Frequency % of EX to add RNG + +// Link Commands +integer LINK_MENU_DISPLAY = 300; +integer LINK_MENU_RETURN = 320; +integer LINK_MENU_TIMEOUT = 330; + + +DisplayMenu(key id) { + string menuDescripter = "thronesitmenu"; + string menuNavigate = "FALSE"; + string menuText = "Select a sitting animation"; + string menuButtons = "Sit~Chilled~Crossed~Slumped~Sleepy~Cozy"; // The buttons, each button separated by a '~'. + + llMessageLinked(LINK_THIS, LINK_MENU_DISPLAY, menuDescripter+"|"+menuNavigate+"|"+menuText+"|"+ menuButtons, id); +} + +//Sets / Updates the sit target moving the avatar on it if necessary. +UpdateSitTarget(vector pos, rotation rot) +{//Using this while the object is moving may give unpredictable results. + llSitTarget(pos, rot);//Set the sit target + key user = llAvatarOnSitTarget(); + if(user)//true if there is a user seated on the sittarget, if so update their position + { + vector size = llGetAgentSize(user); + if(size)//This tests to make sure the user really exists. + { + //We need to make the position and rotation local to the current prim + rotation localrot = ZERO_ROTATION; + vector localpos = ZERO_VECTOR; + if(llGetLinkNumber() > 1)//only need the local rot if it's not the root. + { + localrot = llGetLocalRot(); + localpos = llGetLocalPos(); + } + integer linkNum = llGetNumberOfPrims(); + do + { + if(user == llGetLinkKey( linkNum ))//just checking to make sure the index is valid. + { + //<0.008906, -0.049831, 0.088967> are the coefficients for a parabolic curve that best fits real avatars. It is not a perfect fit. + float fAdjust = ((((0.008906 * size.z) + -0.049831) * size.z) + 0.088967) * size.z; + llSetLinkPrimitiveParamsFast(linkNum, + [PRIM_POS_LOCAL, (pos + <0.0, 0.0, 0.4> - (llRot2Up(rot) * fAdjust)) * localrot + localpos, + PRIM_ROT_LOCAL, rot * localrot]); + jump end;//cheaper but a tad slower then return + } + }while( --linkNum ); + } + else + {//It is rare that the sit target will bork but it does happen, this can help to fix it. + llUnSit(user); + } + } + @end; +}//Written by Strife Onizuka, size adjustment and improvements provided by Talarus Luan + +default +{ + state_entry() + { + llSitTarget(ZERO_VECTOR,ZERO_ROTATION); + vector default_seat = llGetGeometricCenter() - current_sitting_offset; + init_pos = llGetGeometricCenter(); + llSitTarget(default_seat, default_rot); + } + + on_rez(integer start_param) { + llResetScript(); + //llOwnerSay("Reset"); // for debugging + } + + changed(integer change) { + //llOwnerSay("Changes"); // for debugging + if (change & CHANGED_LINK) { + //llOwnerSay("Sat"); // for debugging + key av = llAvatarOnSitTarget(); + integer perm = llGetPermissions(); + if (av) { + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStopAnimation("sit"); + llStartAnimation(current_sitting_anim); + llSetTimerEvent(ex_timer); + } else { + llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); + } + DisplayMenu(av); + } else { + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStopAnimation(current_sitting_anim); + } + llResetScript(); + } + } + } + + run_time_permissions(integer perm) { + key av = llAvatarOnSitTarget(); + if (av) { + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStopAnimation("sit"); + llStartAnimation(current_sitting_anim); + llSetTimerEvent(ex_timer); + } + } + } + + timer() { + key av = llAvatarOnSitTarget(); + if (av) { + integer perm = llGetPermissions(); + if(PERMISSION_TRIGGER_ANIMATION & perm) { + if (can_ex == 1) { + float roll_dem_bones = llFrand(1.0); + if (roll_dem_bones <= ex_frequency) { + llStartAnimation(current_sitting_anim + "Ex"); + } + } + } + } + } + + link_message(integer intSenderNum, integer num, string message, key id) { + if (num == LINK_MENU_RETURN) { + list returnMenu = llParseString2List(message, ["|"], []); + string menuDescriptor = llList2String(returnMenu,0); + + if (menuDescriptor == "thronesitmenu") { + key av = llAvatarOnSitTarget(); + if (av) { + string item = llList2String(returnMenu,1); + //llOwnerSay(item); // for debugging + + string actual_current_sitting_anim = current_sitting_anim; + if (item == "Sit") { + current_sitting_anim = "sit"; + current_sitting_offset = <0.05, 0.65, -0.15>; + can_ex = 0; + } else if (item == "Chilled") { + current_sitting_anim = "throneSitChilled"; + current_sitting_offset = <-0.055, 0.2, 0.125>; + can_ex = 1; + } else if (item == "Crossed") { + current_sitting_anim = "throneSitCrossed"; + current_sitting_offset = <0.01, 0.12, 0.125>; + can_ex = 1; + } else if (item == "Slumped") { + current_sitting_anim = "throneSitSlumped"; + current_sitting_offset = <0.01, 0.12, 0.125>; + can_ex = 1; + } else if (item == "Sleepy") { + current_sitting_anim = "throneSitSleepy"; + current_sitting_offset = <0.01, 0.12, 0.125>; + can_ex = 1; + } else if (item == "Cozy") { + current_sitting_anim = "throneSitCozy"; + current_sitting_offset = <0.01, 0.12, 0.125>; + can_ex = 1; + } + + integer perm = llGetPermissions(); + if(PERMISSION_TRIGGER_ANIMATION & perm) { + llStopAnimation(actual_current_sitting_anim); + vector default_seat = init_pos - current_sitting_offset; + UpdateSitTarget(default_seat, default_rot); + //llSetLinkPrimitiveParamsFast(llGetNumberOfPrims(),[PRIM_POS_LOCAL,default_seat]); + llStartAnimation(current_sitting_anim); + } + + DisplayMenu(av); + } + } + } else if (num == LINK_MENU_TIMEOUT) { + if (message == "thronesitmenu") { + key av = llAvatarOnSitTarget(); + if (av) { + DisplayMenu(av); + } + } + } + } +}