If you do choose to clean it up, add your name and contributions to the comments at the top!
CODE
//Menu-based Multi-animation Chairs
//by Padraig Swordthain
//
//Menu Handler based on the code poetry of ZenMondo Wormser
//Poseball scripting from both Seagle Neville and Dolyn Foley
//
//Yes, this is a slop-bucket of bad and right. I welcome you to make it
//good and right, provided you continue to distribute it freely. You may
//use this in commercial furniture, provided the script remains copyable
//by all.
//
//Global Variables
//*** EDIT THESE VARIABLES TO SUIT YOUR NEEDS ***
string float_text = "";
//Want float text? Stick it in the quotes.
string sit_text="";
//Want to change the text that says "Sit Here" in the object's pie menu?
vector sit_rot = <0, -90, 0>;
//Wrong angle? Change this vector.
vector sit_pos = <-1.1, 0, -0.3>;
//Wrong position? Edit this vector.
string sit_anim = "Meditation (AFK)";
//This is the animation you want to start with.
//You can leave this blank, to start with the alphabetical first in the object's inventory.
integer time = 30;
//Time in seconds before the menu expires. If you've got more than one page, you may want more time.
// *** STOP EDITING HERE, UNLESS YOU REALLY KNOW WHAT YOU'RE DOING ***
integer object_counter=0;
list inventory_list = [];
list menu_list = [];
integer menu_page;
integer last_menu;
integer handle;
integer UserChan = -11811;
key current_user = NULL_KEY;
integer using;
//Functions
//Compact function to put buttons in "correct" human-readable order ~ Redux
//Taken from http://lslwiki.net/lslwiki/wakka.php?wakka=llDialog
list order_buttons(list buttons)
{
return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);
}
//Function to build the two lists we will use
// Could have put it all in state_entry but may be a handy function
// to use in another similar script so I put it here.
BuildLists()
{
integer counter=0;
integer inventory_num = llGetInventoryNumber(INVENTORY_ANIMATION);
while(counter < inventory_num)
{
string object_name = llGetInventoryName(INVENTORY_ANIMATION, counter);
inventory_list = (inventory_list=[]) + inventory_list + object_name;
menu_list = (menu_list=[]) + menu_list + [(string) (++counter) + ")" + object_name];
//Incrementing the the counter in this line. Probably bad practice
//But it solves two problems, incrementing the counter in the loop
// and making a human readable list starting at "1" instead of "0"
}
if(counter % 9 == 0) //Multiples of 9 won't round down right.
{
--counter;
}
last_menu = llFloor(counter / 9.0); //I say 9.0 so it treats it like a float
//and will round down correctly.
}
//Function to Display the pages of the Menu
// Instead of defining my menus ahead of time
// (and in so doing putting a limit on the number of items)
// I build the pages of the menu dynamicaly
DisplayMenu(key id)
{
//These are the buttons, they will be numbers
// Based on what page of the menu we are on.
string b1 = (string) (menu_page *9 +1);
string b2 = (string) (menu_page *9 +2);
string b3 = (string) (menu_page *9 +3);
string b4 = (string) (menu_page *9 +4);
string b5 = (string) (menu_page *9 +5);
string b6 = (string) (menu_page *9 +6);
string b7 = (string) (menu_page *9 +7);
string b8 = (string) (menu_page *9 +8);
string b9 = (string) (menu_page *9 +9);
list menu = [b1, b2, b3, b4, b5, b6, b7, b8, b9, "<<PREV", " ", "NEXT>>"]; //will use the order_buttons function to put these in a good order for llDialog
list menu_text = llList2List(menu_list, menu_page * 9, menu_page * 9 + 8); //This is the part of the list for menu text for this page.
integer menu_length = llGetListLength(menu_text);
if(menu_length < 9) //Don't need all the buttons
{
menu = llDeleteSubList(menu, menu_length, 8); //Trim the menu buttons
}
llDialog(id, llDumpList2String(menu_text, "\n"), order_buttons(menu), UserChan); //Display the Menu
}
default
{
on_rez(integer start_param) {
llResetScript();
}
state_entry() {
llSetText(float_text, <0.0,1.0,1.0>, 1);
llSetSitText(sit_text);
llSitTarget( sit_pos, llEuler2Rot(sit_rot*DEG_TO_RAD) );
// if blank, we look in inventory
if (sit_anim == "") {
sit_anim = llGetInventoryName(INVENTORY_ANIMATION, 0);
// oops, use default
if (sit_anim == "") {
sit_anim = "sit";
}
}
}
// Using state to control sitting
// If you're in this state, no one is sitting
changed(integer change) {
if (change & CHANGED_LINK) {
key avatar = llAvatarOnSitTarget();
if ( avatar != NULL_KEY ) {
llRequestPermissions(avatar,PERMISSION_TRIGGER_ANIMATION);
}
}
}
run_time_permissions(integer parm) {
if(parm == PERMISSION_TRIGGER_ANIMATION) {
llStopAnimation("sit");
llStartAnimation(sit_anim);
state sitting;
}
}
}
state sitting
{
state_entry()
{
key avatar = llAvatarOnSitTarget();
menu_page = 0;
UserChan = -((integer)llFrand(2147483646.0) + 1); //Choose a random negative channel to use to avoid crossttalk with other chairs
BuildLists();
DisplayMenu(avatar);
handle = llListen(UserChan, "", avatar, "");
llSetTimerEvent(time); //Time to make a choice or reset if walk away
}
touch_start(integer total_number)
{if(using) //Object in use
{
if(llDetectedKey(0) != llAvatarOnSitTarget())
{
//Communicate using llDialog we are in a library after all
// and its even quieter than a whisper.
llDialog(llDetectedKey(0), "Sorry, you're not sitting here.", ["OK"], 1181111811);
}
else // Our user
{
DisplayMenu(current_user); //Give the menu again but not more time
// This is in case they accidently hit "ignore"
}
}
else //Giver is available and ready for use
{
current_user = llAvatarOnSitTarget();
using = TRUE;
handle = llListen(UserChan, "", current_user, "");
llSetTimerEvent(time);
DisplayMenu(current_user);
}
}
listen(integer channel, string name, key id, string message)
{
if(message == " ")
{
DisplayMenu(current_user);
llSetTimerEvent(0);
llListenRemove(handle);
using = FALSE;
current_user = NULL_KEY;
menu_page = 0;
llSetText(float_text, <0, 1, 1>, 1.0);
}
else if(message == "<<PREV")
{
menu_page--;
if(menu_page == -1)
{
menu_page = last_menu;
}
DisplayMenu(current_user);
}
else if(message == "NEXT>>")
{
menu_page++;
if(menu_page > last_menu)
{
menu_page = 0;
}
DisplayMenu(current_user);
}
else //Patron Chose a Number
{
llSetTimerEvent(0);
llListenRemove(handle);
integer get_item = (integer) message;
get_item--; //Humans like to count from 1, but computers like 0 better.
llStopAnimation(sit_anim);
sit_anim = llList2String(inventory_list, get_item);
llStartAnimation(sit_anim);
using = FALSE;
current_user = NULL_KEY;
menu_page = 0;
llSetText(float_text, <0, 1, 1>, 1.0);
}
}
timer()
{
llSetTimerEvent(0);
llListenRemove(handle);
llDialog(current_user, "Time expired. To select a sit animation, please click your seat." , ["OK"], 1181111811);
using= FALSE;
current_user = NULL_KEY;
menu_page = 0;
llSetText(float_text, <0, 1, 1>, 1.0);
}
changed(integer change)
{
if(change & CHANGED_INVENTORY)
{
llResetScript();
}
if (change & CHANGED_LINK) {
llStopAnimation(sit_anim);
llResetScript();
}
}
}