See if it helps. All the script below is just one long script.
`// Script to present a dialog populated with a list of notecards
// from the prims inventory
//
// Note that only the first 24 characters of the notecard names
// are actually used - as only 24 chars can be placed in a dialog
// button. This means that if two notecards have the first 24 chars
// the same, the second will be ignored ...
//
// Note however that usually, buttons don't display more than, say,
// around 10 or so characters anyway!!
//
// Kimm Paulino
// Written for Vikki Hastings, June 2011
// Configure the behaviour we want
string gFloatingText = "Click for notecards"; // Set to "" to disable
vector gFloatingTextColour = <1.0, 1.0, 1.0>;
float gFloatingTextAlpha = 1.0;
integer gChannel;
integer gMenuPage;
integer gNumNotecards;
list gNotecards;
integer getRandomChannel ()
{
// Based on http://tali.appspot.com/html/scripting/snippets.html
// Always leaves 17th bit set (so never a number less than 65535)
// Always leaves sign bit unset (so is always positive)
integer pos_int = (((integer)llFrand(16384)) << 17) | 65536 | ((integer)llFrand(65535));
return -pos_int;
}
if (gNumNotecards == 0)
{
llOwnerSay ("Note: There are no notecards in this prim to give to people ...");
return;
}
integer i;
for (i=0; i<gNumNotecards; i++)
{
string nc = llGetInventoryName (INVENTORY_NOTECARD, i);
// Only store the first 24 characters of the name as this is all we can
// show in a dialog anyway
gNotecards += [llGetSubString (nc, 0, 23)];
}
}
give_notecard (key id, string nc)
{
integer idx = llListFindList (gNotecards, [nc]);
if (idx == -1)
{
// Didn't find it in the list - might not be a notecard
return;
}
// Now need to find the notecard that matches from the inventory
// and give it out
integer i;
for (i=0; i<gNumNotecards ; i++)
{
string nc_full = llGetInventoryName(INVENTORY_NOTECARD, i);
if (llGetSubString (nc_full, 0, 23) == nc)
{
// This is the one
llGiveInventory (id, nc_full);
return;
}
}
// if get here, then didn't get a match ... hmm
}
show_dialog (key id)
{
list buttons = [];
if (gNumNotecards == 0)
{
llDialog (id, "There are no notecards to give at present.\nThe Owner doesn't appear to have put any in yet.", [], gChannel);
return;
}
// If several people are using the giver, then it is possible
// for gMenuPage to go negative or too high
if (gMenuPage < 0)
{
// Reset ...
gMenuPage = 0;
}
integer num_pages = ((gNumNotecards+8)/9);
if (gMenuPage >= num_pages)
{
// gMenuPage is an index starting at 0...
// max is a 1...
gMenuPage = num_pages-1;
}
// Note: This yields notecards counting as follows:
// 0 to 8 = first page,
// 9 to 17 = next page, etc
integer first_nc = gMenuPage * 9;
integer last_nc = first_nc + 9 - 1;
if (last_nc >= gNumNotecards)
{
// recall last_nc indexed from 0, but
// gNumNotecards is indexed from 1
last_nc = gNumNotecards-1;
}
state_entry()
{
llSetText (gFloatingText, gFloatingTextColour, gFloatingTextAlpha);
read_notecards();
gMenuPage = 0;
gChannel = getRandomChannel();
// Would be less laggy to close listen when not in use
// but then if two people attempted to use the giver,
// it wouldn't be able to cope. This way, they can both
// use it at the same time ...
llListen (gChannel, "", "", "");
}
touch_start(integer total_number)
{
// Start menu system again. Note that I don't do anything special
// with several people trying to touch it at the same time - it will
// always overlap the processing of gMenuPage, but all that will
// happen is that peoples next/back might be a bit quirky for a while.
// Eventually, they will sort themselves out!
gMenuPage = 0;
show_dialog (llDetectedKey(0));
}
listen (integer channel, string name, key id, string msg)
{
if (channel == gChannel)
{
if (msg == MENU_BACK)
{
gMenuPage--;
show_dialog (id);
}
else if (msg == MENU_TOP)
{
gMenuPage = 0;
show_dialog (id);
}
else if (msg == MENU_NEXT)
{
gMenuPage++;
show_dialog (id);
}
else
{
// should be something in the inventory to give out
give_notecard (id, msg);
}
}
}
changed (integer change)
{
if (change & CHANGED_INVENTORY)
{
llResetScript();
}
}
See if it helps. All the script below is just one long script. `// Script to present a dialog populated with a list of notecards // from the prims inventory // // Note that only the first 24 characters of the notecard names // are actually used - as only 24 chars can be placed in a dialog // button. This means that if two notecards have the first 24 chars // the same, the second will be ignored ... // // Note however that usually, buttons don't display more than, say, // around 10 or so characters anyway!! // // Kimm Paulino // Written for Vikki Hastings, June 2011
// Configure the behaviour we want string gFloatingText = "Click for notecards"; // Set to "" to disable vector gFloatingTextColour = <1.0, 1.0, 1.0>; float gFloatingTextAlpha = 1.0;
integer gChannel; integer gMenuPage; integer gNumNotecards; list gNotecards;
string MENU_NEXT="Next>"; string MENU_TOP="Top"; string MENU_BACK="<Back"; string MENU_SPACE=" ";
integer getRandomChannel () { // Based on http://tali.appspot.com/html/scripting/snippets.html // Always leaves 17th bit set (so never a number less than 65535) // Always leaves sign bit unset (so is always positive) integer pos_int = (((integer)llFrand(16384)) << 17) | 65536 | ((integer)llFrand(65535)); return -pos_int; }
read_notecards () { gNumNotecards = llGetInventoryNumber (INVENTORY_NOTECARD); gNotecards = [];
}
give_notecard (key id, string nc) { integer idx = llListFindList (gNotecards, [nc]); if (idx == -1) { // Didn't find it in the list - might not be a notecard return; }
}
show_dialog (key id) { list buttons = [];
// llOwnerSay ("Menu Page: " + (string)gMenuPage); // llOwnerSay ("First NC: " + (string)first_nc); // llOwnerSay ("Last NC: " + (string)last_nc);
}
default { on_rez (integer start_param) { llResetScript(); }
`