Help with Multi-User level Notecard giver
|
|
Waneman Tennant
Registered User
Join date: 28 Jul 2006
Posts: 2
|
08-03-2007 12:14
Greetings, I have searched high and low for a script that will do my bidding..hehe I retooled this from Newgate Ludd's Multi Landmark Menu Script. I hope he will forgive me. Anyway, it works as is, but I need to be able to have a version that I can set permissions to. Such as Administrators who can only access certain notcards in the object. It can be a seperate script for a seperate object holding only notecards for administrator access but there will be more than one administrator. Perhaps by using their user key. As a second wish from anyone who helps me here, At the current state, the notecards are listed with corresponding numbers, Those numbers are then placed on the selection buttons. It would be my wish that the notecard names WERE the selection buttons. Thank you in advance for all the help you all give and thank you Newgate Ludd for such a great script. If you don't wish me to use this, I will not. I am using it only for personal use. // This script was derived from // Newgate Ludd's Multi Landmark Menu Script // list Notecards; // List of Notecard names integer maxNotecards; // Number of Notecards integer CHANNEL; // Channel on which Dialog listens list Choices; // List being chosen From integer Listening = 0; // Listen handle integer pagesize = 5; // Number of Items per Dialog string title; // text of Dialog integer first; // first index into list integer i; // -------------------------- UpdateListen(key id) { CancelListen(); CHANNEL = 0 - (integer)llFrand(2147483647); Listening = llListen(CHANNEL,"",id,""); llSetTimerEvent(20); } // -------------------------- CancelListen() { if(Listening > 0) llListenRemove(Listening); Listening = 0; llSetTimerEvent(0); } // -------------------------- ShowMenu(key avatar) { title = "Which Notecard would you like?"; Choices = [ ]; // Now add the items if(first > 0) Choices += "<<"; if(maxNotecards > (first + pagesize)) { Choices += ">>"; }
// Add x items for(i = 0;i < pagesize;i++) { integer j = (i + first); string num = (string)j;
string strname = llList2String(Notecards,j); if( llStringLength(strname) > 0) { title += "\n" + num + ") " + strname; Choices += [ num ]; } } // finally show the dialog UpdateListen(avatar); llDialog(avatar, title, Choices, CHANNEL); } // -------------------------- GetNotecardList() { // Clear out any existing items Notecards = []; // Get the number of Landmarks integer number = llGetInventoryNumber(INVENTORY_NOTECARD); // iterate through them all while(--number >= 0) { string name = llGetInventoryName(INVENTORY_NOTECARD, number); Notecards = (Notecards = []) + Notecards + [ name ]; } } // -------------------------- default { state_entry() { llOwnerSay("Initialising, Please wait..."); GetNotecardList(); maxNotecards = llGetListLength(Notecards); llOwnerSay("Ready. " + (string)maxNotecards + " Available."); llAllowInventoryDrop(TRUE); }
touch_start(integer total_number) { first = 0; ShowMenu(llDetectedKey(0) ); }
listen(integer channel, string name, key id, string message) { CancelListen(); // verify dialog choice if("<<" == message) { first -= pagesize; if(first < 0) first = 0; ShowMenu(id); } else if(">>" == message) { first += pagesize; if(first > maxNotecards) first = (maxNotecards - pagesize); ShowMenu(id); } else { integer index = llListFindList(Choices, [message]); if(index >= 0) { string NotecardName = llList2String(Notecards,(integer)message); llGiveInventory(id,NotecardName); } } }
timer() { CancelListen(); }
changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); } on_rez(integer num) { llResetScript(); } }
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
LOL, No Newgy doesn't mind
08-03-2007 13:47
Anything I have ever posted is obviously open for any and all to enhance or use, so feel free to do so, thanks for asking and for the acknowledgement. As for your questions. The reason the Text isnt placed on the buttons is due to the limitations of the LSL Dialog system. You can only have names up to 24 (?) characters in length and even then only 10 or 11 will be displayed. Given the above limitations you can place your text directly on the buttons by using the following code: // -------------------------- ShowMenu(key avatar) { title = "Which Notecard would you like?"; Choices = [ ]; // Now add the items if(first > 0) Choices += "<<"; if(maxNotecards > (first + pagesize)) { Choices += ">>"; } // Add x items for(i = 0;i < pagesize;i++) { integer j = (i + first); string num = (string)j; string strname = llList2String(Notecards,j); if( llStringLength(strname) > 0) { Choices += [ strname ]; } } // finally show the dialog UpdateListen(avatar); llDialog(avatar, title, Choices, CHANNEL); }
The listen event then needs to change to cope :
listen(integer channel, string name, key id, string message) { CancelListen(); // verify dialog choice if("<<" == message) { first -= pagesize; if(first < 0) first = 0; ShowMenu(id); } else if(">>" == message) { first += pagesize; if(first > maxNotecards) first = (maxNotecards - pagesize); ShowMenu(id); } else { integer index = llListFindList(Notecards, [message]); if(index >= 0) { string NotecardName = llList2String(Notecards,index); llGiveInventory(id,NotecardName); } } }
Access permissions are a different problem. I take it you mean only certain people can be given certain notecards? Its basically a multilevel access system just like a door lock. Each access level has a notecard defining who is in that group. You then have a further notecard that indexes which notecards belong to which group. If the number of people being 'grouped' is small enough, less than say 50, then you could use a single notecard to list access rights. More than that and I'd think about using multiple scripts, one for each access group.
_____________________
I'm back......
|
|
Thomas Lake
Registered User
Join date: 23 Jul 2006
Posts: 2
|
11-06-2007 09:54
Hello, this script was great, just what I was looking myself to use. But noticed few things that concern me:
1. The notecards will be sorted by the name but in reverse order, so how this can be changed that they would be alphabetically ordered correctly from A to Z, not from Z to A?
2. Does the menu have timeout if no choice will not be done? And if not, how this could be done in the script?
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
11-06-2007 17:13
change Choices += [strname]; to Choices = (list)strname + Choices; or to use less memory use Choices = (Choices=[]) + (list)strname + Choices; you could also use llSortList( Choices, 1, TRUE ) after after making the list, but I'd use the previous example
you can cancel all listens after a timeout using llSetTimerEvent( 30.0 ); each time you call the listen (say on touch?)
then in the timer llSetTimerEvent( .0 ); state reflect;
then in state reflect state_entry(){ state default; //-- or whatever your working state for listens is }
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Thomas Lake
Registered User
Join date: 23 Jul 2006
Posts: 2
|
11-06-2007 23:12
Hello again, and thank you for the answer but I just noticed I wasnt clear enough to mention I referred to the script that was in the first post of this thread, made by Waneman. And that script works bit different than the one with the notecard names in the button.
So originally I was wondering if the notecards could be sorted alphabetically in that first script, where button names will be those numbers assigned to the notecards.
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
11-07-2007 04:42
so you are looking to do a list of numbers on the buttons, referencing a number tacked on to the notecard name?
easy enough, create your notecard list and at the same time create a button_list of numbers (you can use the loop counter number as the data even (or you could use something like llGetSubString( notecardName, -2, -1))
then in your listen, when it hears the number, either use llListFindList( button_list, listen_msg ) to get the index to use in notecard_list, or if you built it directly from the counter number, just use the number as is for the index of notecard_list
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Talia Beery
Registered User
Join date: 10 Feb 2008
Posts: 2
|
 I'm bad at this game...
03-06-2008 07:27
OK, so, I'm absolutely HORRIBLE with scripting. What I need is to have an object that, when clicked, gives several options for the notecard you're to receive. For example, the notecard giver will be for "Business" and then you'll have options to receive the "Accounting" notecard, the "E-Commerce" notecard, or the "Office Management" notecard.
Can someone give me some SPECIFIC instructions as to how to do this? I looked at the script in this thread, and it just makes my brain hurt. And I also see where there are instructions commented out, but I still don't get it. (I told you, I'm awful with this!) Any help you could provide would be incredibly appreciated!
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
03-06-2008 12:14
It depends a little on whether all options are going to be disjoint. From those you mention, it appears this might be so, and the larger categories are simply for convenient grouping and navigation. What I mean by this is that you aren't likely to have "Home/Accounting" and "Business/Accounting", or if you did, you'd rename them to something like "Home/Personal Accunting" and "Business/Accounting". Likewise you wouldn't want any specific subject to match a category, so you wouldn't want "Business/..." and "Home/Business". If all choices ARE disjoint, it makes things pretty simple in that you can just start a single listen on a channel (I recommend a large negative channel). If choices AREN'T disjoint, you might need something like a main dialog channel and a channel for each category, with listens on each. I'll assume you are going to go with the former. Here is how I would handle it. (Note that this code has NOT been compiled, so you might need to fix some small syntax issues yourself. It should give you the idea though.) //// Constants
string HOME_CATEGORY = "Home"; list HOME_CHOICES = [ "Housecleaning", "Laundry", "Home Repair" ];
string BUSINESS_CATEGORY = "Business"; list BUSINESS_CHOICES = [ "Accounting", "Office Management", "Supervising" ];
string HEALTH_CATEGORY = "Health"; list HEALTH_CHOICES = [ "Nutrition", "Fitness", "Stress Management" ];
list CATEGORIES = [ HOME_CATEGORY, BUSINESS_CATEGORY, HEALTH_CATEGORY ];
//// Variables
integer dialogChannel;
//// Functions
integer randomNegativeChannel() { return 0x80000000|(((integer)llFrand(1<<15))<<16)|(integer)llFrand(1<<16); }
//// States
default { state_entry() { dialogChannel = randomNegativeChannel(); llListen(dialogChannel, "", NULL_KEY, ""); }
touch(integer nDetected) { integer i; for (i = 0; i < nDetected; ++i) { llDialog( llDetectedKey(i), "Choose a category:", CATEGORIES, dialogChannel); } }
listen(integer channel, string name, key id, string message) { if (message == HOME_CATEGORY) { llDialog( id, "Category "+message+":" HOME_CHOICES, dialogChannel); } else if (message == BUSINESS_CATEGORY) { llDialog( id, "Category "+message+":" BUSINESS_CHOICES, dialogChannel); } else if (message == HEALTH_CATEGORY) { llDialog( id, "Category "+message+":" HEALTH_CHOICES, dialogChannel); } else { if (llGetInventoryType(message) != INVENTORY_NOTECARD) { llInstantMessage( id, "Sorry, but I don't currently have any information about '"+ message+"'"); return; }
llGiveInventory(id, message); } } }
|