raynaglieri / MILE4STEM_FSU

0 stars 1 forks source link

Multicard giver script -> High #37

Closed MariyaPa closed 6 years ago

MariyaPa commented 6 years ago

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 = [];

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;
}

// llOwnerSay ("Menu Page: " + (string)gMenuPage); // llOwnerSay ("First NC: " + (string)first_nc); // llOwnerSay ("Last NC: " + (string)last_nc);

if (gMenuPage > 0)
{
    buttons += [MENU_BACK];
}
else
{
    buttons += [MENU_SPACE];
}

if (gMenuPage == 0)
{
    buttons += [MENU_SPACE];
}
else
{

    buttons += [MENU_TOP];
}

// If not on the last page, and there are more pages to come ...
if (gNumNotecards > 9 && gMenuPage < (num_pages-1))
{
    buttons += [MENU_NEXT];
}
else
{
    buttons += [MENU_SPACE];
}

integer i;
for (i=first_nc; (i <= last_nc) && (i < gNumNotecards); i++)
{
    buttons += [llList2String (gNotecards, i)];
}

llDialog (id, "\n\n(click \"Ignore\" when done)", buttons, gChannel);

}

default { on_rez (integer start_param) { llResetScript(); }

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();
    }
}

`

raynaglieri commented 6 years ago

Initial script is done.