01-26-2009 13:24
Okay, so this is a dirty cut-and-paste job that I patched together from about three scripts I had laying around. It mostly does what I want it to -- i.e. it gives a menu of all animations in the prim it's in, and you can pick one -- but it's an ugly, dirty hackjob, and really needs someone to make it less ugly. I'm tossing it here, instead of the library, because in this condition, it's just not library material.

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();
}
}
}
_____________________
Incidental Radio :: Because nothing is by design