Where have I gone wrong?
|
|
Krazzora Zaftig
Do you have my marbles?
Join date: 20 Aug 2005
Posts: 649
|
11-29-2006 16:49
OK I was trying to test out a menu and I have two issues but honestly I am unsure of how to fix it. I know I have to many "if/else if" statements and I can't get the submenu puttons to repond to the LLsay even when I shorten the number of statements. I sadly do need each menu as bsaicly it is going to be submenus for each side of a prim. Can anyone help me cause I am going nuts. integer CHANNEL = -666; list MENU_MAIN = ["Flexi", "Phantom", "EMERGENCY", "Inside", "Outside", "All"]; list MENU_INSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"]; list MENU_OUTSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"]; list MENU_ALL = ["Back", "Texture", "100", "75", "50", "25", "0"]; default { state_entry() { llListen(CHANNEL, "", NULL_KEY, ""  ; } touch_start(integer total_number) { llDialog(llDetectedKey(0), "What is your wish?", MENU_MAIN, CHANNEL); } listen(integer channel, string name, key id, string message) { if (llListFindList(MENU_MAIN + MENU_INSIDE, [message]) != -1) { llSay(0, name + " picked the option '" + message + "'."  ; // output the answer if (message == "Outside" llDialog(id, "Pick an option to change outside of curtains!", MENU_OUTSIDE, CHANNEL); else if (message == "Inside" llDialog(id, "Pick an option to change inside of curtains!", MENU_INSIDE, CHANNEL); else if (message == "All" llDialog(id, "Pick an option to change both sides of the curtains!", MENU_ALL, CHANNEL); else if (message == "Back" llDialog(id, "What is your wish?", MENU_MAIN, CHANNEL); else if (message == "Flexi"  llSay(0, "Flexi"  ; else if (message == "Phantom"  llSay(0, "Phantom"  ; else if (message == "EMERGENCY"  llSay(0, "Emergency"  ; else if (message == "MENU_INSIDE|texture"  llSay(0, "MENU_INSIDE|texture"  ; else if (message == "MENU_INSIDE|100"  llSay(0, "MENU_INSIDE|100"  ; else if (message == "MENU_INSIDE|75"  llSay(0, "MENU_INSIDE|75"  ; else if (message == "MENU_INSIDE|50"  llSay(0, "MENU_INSIDE|50"  ; else if (message == "MENU_INSIDE|25"  llSay(0, "MENU_INSIDE|25"  ; else if (message == "MENU_INSIDE|0"  llSay(0, "MENU_INSIDE|0"  ; else if (message == "MENU_OUTSIDE|texture"  llSay(0, "MENU_OUTSIDE|texture"  ; else if (message == "MENU_OUTSIDE|100"  llSay(0, "MENU_OUTSIDE|100"  ; else if (message == "MENU_OUTSIDE|75"  llSay(0, "MENU_OUTSIDE|75"  ; else if (message == "MENU_OUTSIDE|50"  llSay(0, "MENU_OUTSIDE|50"  ; else if (message == "MENU_OUTSIDE|25"  llSay(0, "MENU_OUTSIDE|25"  ; else if (message == "MENU_OUTSIDE|0"  llSay(0, "MENU_OUTSIDE|0"  ; else if (message == "MENU_ALL|texture"  llSay(0, "MENU_ALL|texture"  ; else if (message == "MENU_ALL|100"  llSay(0, "MENU_ALL|100"  ; else if (message == "MENU_ALL|75"  llSay(0, "MENU_ALL|75"  ; else if (message == "MENU_ALL|50"  llSay(0, "MENU_ALL|50"  ; else if (message == "MENU_ALL|25"  llSay(0, "MENU_ALL|25"  ; else if (message == "MENU_ALL|0"  llSay(0, "MENU_ALL|0"  ; } else llSay(0, name + " picked invalid option '" + llToLower(message) + "'."  ; } }
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
11-29-2006 17:03
Parser Stack depth error at line #65 It does work if you cut some out. I know there are some that have run into this before and maybe they will have another solution. What comes to my mind would maybe if it is one of the submenu, moving it into another state??????
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
|
11-29-2006 17:08
From: Krazzora Zaftig list MENU_INSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"];
default {
listen(integer channel, string name, key id, string message) { //... else if (message == "Inside") llDialog(id, "Pick an option to change inside of curtains!", MENU_INSIDE, CHANNEL); // ... else if (message == "MENU_INSIDE|texture") // ... } }
The llDialog doesn't quite work like this. When the user clicks one of the button it provides, the result is just the text shown on the button... so you are never going to receive "MENU_INSIDE|texture" as result of it, but just "texture" It's up to the script to keep track on what menu was fired last so it can match the text received through dialog with list of relevant options and act accordingly, and how exactly to go about it is up to individual scripter ^^;;
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
11-29-2006 17:12
This works PS I used PHP inside [] before script and /php inside [] at end of script for it to display as a script and I added indents. You can see how much more readable it is.
integer CHANNEL = -666; list MENU_MAIN = ["Flexi", "Phantom", "EMERGENCY", "Inside", "Outside", "All"]; list MENU_INSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"]; list MENU_OUTSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"]; list MENU_ALL = ["Back", "Texture", "100", "75", "50", "25", "0"]; default { state_entry() { llListen(CHANNEL, "", NULL_KEY, ""); } touch_start(integer total_number) { llDialog(llDetectedKey(0), "What is your wish?", MENU_MAIN, CHANNEL); } listen(integer channel, string name, key id, string message) { if (llListFindList(MENU_MAIN + MENU_INSIDE, [message]) != -1) { llSay(0, name + " picked the option '" + message + "'."); // output the answer if (message == "Outside") llDialog(id, "Pick an option to change outside of curtains!", MENU_OUTSIDE, CHANNEL); else if (message == "Inside") llDialog(id, "Pick an option to change inside of curtains!", MENU_INSIDE, CHANNEL); else if (message == "All") llDialog(id, "Pick an option to change both sides of the curtains!", MENU_ALL, CHANNEL); else if (message == "Back") llDialog(id, "What is your wish?", MENU_MAIN, CHANNEL); else if (message == "Flexi") llSay(0, "Flexi"); else if (message == "Phantom") llSay(0, "Phantom"); else if (message == "EMERGENCY") llSay(0, "Emergency"); else if (message == "MENU_INSIDE|texture") llSay(0, "MENU_INSIDE|texture"); else if (message == "MENU_INSIDE|100") llSay(0, "MENU_INSIDE|100"); else if (message == "MENU_INSIDE|75") llSay(0, "MENU_INSIDE|75"); else if (message == "MENU_INSIDE|50") llSay(0, "MENU_INSIDE|50"); else if (message == "MENU_INSIDE|25") llSay(0, "MENU_INSIDE|25"); else if (message == "MENU_INSIDE|0") llSay(0, "MENU_INSIDE|0"); else if (message == "MENU_OUTSIDE|texture") llSay(0, "MENU_OUTSIDE|texture"); else if (message == "MENU_OUTSIDE|100") llSay(0, "MENU_OUTSIDE|100"); else if (message == "MENU_OUTSIDE|75") llSay(0, "MENU_OUTSIDE|75"); else if (message == "MENU_OUTSIDE|50") llSay(0, "MENU_OUTSIDE|50"); else if (message == "MENU_OUTSIDE|25") llSay(0, "MENU_OUTSIDE|25"); else if (message == "MENU_OUTSIDE|0") llSay(0, "MENU_OUTSIDE|0"); else if(message == "MENU_ALL") state all; } else llSay(0, name + " picked invalid option '" + llToLower(message) + "'."); } } state all { state_entry() { llListen(CHANNEL, "", NULL_KEY, ""); } listen(integer channel, string name, key id, string message) { if (message == "MENU_ALL|texture") llSay(0, "MENU_ALL|texture"); else if (message == "MENU_ALL|100") llSay(0, "MENU_ALL|100"); else if (message == "MENU_ALL|75") llSay(0, "MENU_ALL|75"); else if (message == "MENU_ALL|50") llSay(0, "MENU_ALL|50"); else if (message == "MENU_ALL|25") llSay(0, "MENU_ALL|25"); else if (message == "MENU_ALL|0") llSay(0, "MENU_ALL|0"); else state default; } }
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Krazzora Zaftig
Do you have my marbles?
Join date: 20 Aug 2005
Posts: 649
|
11-29-2006 17:16
Joannah The say thing was mostly for my understanding. honestly I am going to replace the llsay commands later. with my actual requests. I just wanted to make sure each menu works right before implementing. The issues I know need fixing are 1) To many else if statements but they need to be there. 2) They do say just texture or such instead of MENU_INSIDE|texture but only on the main menu. Is it cause I have the MENU_INSIDE| it doesn't answer back on sub menus?
|
|
Krazzora Zaftig
Do you have my marbles?
Join date: 20 Aug 2005
Posts: 649
|
11-29-2006 17:17
thank you Jesse Can you tell I am a novice at the scripting and forums. >_<
|
|
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
|
11-29-2006 17:20
From: Krazzora Zaftig The say thing was mostly for my understanding. honestly I am going to replace the llsay commands later. with my actual requests. I just wanted to make sure each menu works right before implementing. Sorry i wasn't too clear there ^^;; i wasn't referring to the llSay() commands you have there, but to the if( message == "MENU_INSIDE|texture" part. The thing is, the "MENU_INSIDE|" thing is never added to the text you receive in the listen() event when the user clicks the button, so that condition is never met and hence your functions which are expected to handle the sub-menus never get to execute...
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
11-29-2006 17:28
In general, to avoid the limit on conditionals.. You can do something like: if (blah) { if (more blah) { stuff; } else if (more blah) { stuff; } else if (more blah) { stuff; } return; } //This way we can break the whole lot in half and continue.. if (blah) { if (more blah) { stuff; } else if (more blah) { stuff; } else if (more blah) { stuff; } }
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
11-29-2006 17:30
From: Joannah Cramer Sorry i wasn't too clear there ^^;; i wasn't referring to the llSay() commands you have there, but to the if( message == "MENU_INSIDE|texture" part. The thing is, the "MENU_INSIDE|" thing is never added to the text you receive in the listen() event when the user clicks the button, so that condition is never met and hence your functions which are expected to handle the sub-menus never get to execute... It surprised me also but it all works fine. I dropped it in a prim to double check. Strange!!! EDIT. I forgot to point out to Krazzora again that I am sure there is a better way to do it besides breaking it into two states. It was just all I could think of at the time. I am sure you will recieve more responses to your query. Welcome to the wonderful world of scripting.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Krazzora Zaftig
Do you have my marbles?
Join date: 20 Aug 2005
Posts: 649
|
11-29-2006 17:41
Yeah I am taking all this stright from the wiki example. It seems to work and I HAVE gotten it to answer me "texture" by doing this: else if (message == "Texture") llSay(0, "texture666"); Problem is it makes ALL the "Texture" buttons say this which is a problem. The three texture buttons eventually will actually send out different messages..which I can't figure out how to tell the menu that each button should not refference the same message. Hence the if( message == "MENU_INSIDE|texture")
|
|
Joannah Cramer
Registered User
Join date: 12 Apr 2006
Posts: 1,539
|
11-29-2006 18:41
From: Jesse Barnett It surprised me also but it all works fine. I dropped it in a prim to double check. Strange!!! Yes it'll work in the sense it's not error to test input against text that has no chance to appear, it's just a bit futile ^^;; a simple way to kill two birds with one stone: // pseudocode string active_menu;
listen( ... ) {
if( active_menu == "main" ) { // handle main menu here if( message == "Inside" ) { active_menu = "inside"; llDialog( ... MENU_INSIDE ... ); } else if( message == "Outside" ) { active_menu = "outside"; llDialog( ... MENU_OUTSIDE ... ); } // ... } else if( active_menu == "inside" ) { // handle inside menu here if( message == "Back" ) { active_menu = "main"; llDialog( ... MENU_MAIN ... ); } else if( message == "Texture" ) { set_inside_texture(); } // ... } else if( active_menu == "outside" ) { // handle outside menu here if( message == "Back" ) { active_menu = "main"; llDialog( ... MENU_MAIN ... ); } else if( message == "Texture" ) { set_outside_texture(); } // ... } }
... you break the huge if-else list into smaller multi-level chunks, speed up the tests a little and don't have to worry about button having the same text in more than one sub-menu.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
11-29-2006 18:58
Much nicer!!!!!! 
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Krazzora Zaftig
Do you have my marbles?
Join date: 20 Aug 2005
Posts: 649
|
11-29-2006 20:19
Sadly I have to head to bed but just tried what you gave me Jesse and still getting an error on implmenting. I had to reshape it a bit visually cause I kept getting tons of syntax errors. So needed to see it in more spread out parts. integer CHANNEL = -666; list MENU_MAIN = ["Flexi", "Phantom", "EMERGENCY", "Inside", "Outside", "All"]; list MENU_INSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"]; list MENU_OUTSIDE = ["Back", "Texture", "100", "75", "50", "25", "0"]; list MENU_ALL = ["Back", "Texture", "100", "75", "50", "25", "0"]; default { state_entry() { llListen(CHANNEL, "", NULL_KEY, ""); } touch_start(integer total_number) { llDialog(llDetectedKey(0), "What is your wish?", MENU_MAIN, CHANNEL); } listen(integer channel, string name, key id, string message) { if (llListFindList(MENU_MAIN + MENU_INSIDE, [message]) != -1) { if( active_menu == "main" ) { // handle main menu here if( message == "Inside" ) { active_menu = "inside"; llDialog(id, "Pick an option to change inside of curtains!", MENU_OUTSIDE, CHANNEL); } else if( message == "Outside" ) { active_menu = "outside"; llDialog(id, "Pick an option to change outside of curtains!", MENU_OUTSIDE, CHANNEL); } else if( message == "All" ) { active_menu = "all"; llDialog(id, "Pick an option to change All sides of curtains!", MENU_OUTSIDE, CHANNEL); } // ... } else if( active_menu == "inside" ) { // handle inside menu here if( message == "Back" ) { active_menu = "main"; llDialog(id, "What is your wish?", MENU_MAIN, CHANNEL); } else if( message == "Texture" ) { set_inside_texture();} // ... } else if( active_menu == "outside" ) { // handle inside menu here if( message == "Back" ) { active_menu = "main"; llDialog(id, "What is your wish?", MENU_MAIN, CHANNEL); } else if( message == "Texture" ) { set_inside_texture(); } // ... } else if( active_menu == "inside" ) { // handle inside menu here if( message == "Back" ) { active_menu = "main"; llDialog(id, "What is your wish?", MENU_MAIN, CHANNEL); } else if( message == "Texture" ) { set_inside_texture(); } // ... } } } }
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
11-30-2006 01:04
here is how I would handle the problem. I have taken a few liberties based on your original code:- All of your sub menu options are identical, so I have assumed that only one menu is required. If this is not to be the case then a little it of rework will be needed. I have added stub's for all of the functions that I dont know the purpose off. All you need do is flesh them out. I have assumes that the texture menu will be a set of further options, how you build this will affect the code by adding a further list etc. I personally dislike hard coded channels but have retained it since it is a minor item. integer CHANNEL = -666;
integer Listening = 0; integer listenchannel = 0;
// Which menu / mode are we in integer mode = 0; integer MODE_ALL = 0; integer MODE_INSIDE = 1; integer MODE_OUTSIDE = 2;
list MENU_MAIN = ["Flexi", "Phantom", "EMERGENCY", "Inside", "Outside", "All"]; list MENU_OPTIONS = ["Back", "Texture", "100", "75", "50", "25", "0"];
UpdateListen(key id) { CancelListen(); Listening = llListen(CHANNEL,"",id,""); llSetTimerEvent(30); }
CancelListen() { if(Listening > 0) llListenRemove(Listening); Listening = 0; llSetTimerEvent(0); }
// Main Menu Dialog ShowMainMenu(key id) { string text = "Main Menu\nPlease Select an Option"; // finally show the dialog llDialog(id,text,MENU_MAIN,listenchannel); UpdateListen(id); } ShowInsideMenu(key id) { string text = "Pick an option to change inside of curtains!"; // finally show the dialog llDialog(id,text,MENU_OPTIONS,listenchannel); UpdateListen(id); mode = MODE_INSIDE; } ShowOutsideMenu(key id) { string text = "Pick an option to change outside of curtains!"; // finally show the dialog llDialog(id,text,MENU_OPTIONS,listenchannel); UpdateListen(id); mode = MODE_OUTSIDE; } ShowAllMenu(key id) { string text = "Pick an option to change both sides of the curtains!"; // finally show the dialog llDialog(id,text,MENU_OPTIONS,listenchannel); UpdateListen(id); mode = MODE_ALL; }
// To be fleshed out as and when.... // Id passed in to allow further menu related useage ShowTextureMenu(key id) { }
HandleFlexi(key id) { }
HandlePhantom(key id) { }
HandleEmergency(key id) { }
// I am guessing you will be using the value to set an alpha HandleAll(integer value) { }
HandleInside(integer value) { }
HandleOutside(integer value) { }
default { state_entry() { } touch_start(integer total_number) { ShowMainMenu(llDetectedKey(0)); } timer() { CancelListen(); state Running; }
listen( integer channel, string name, key id, string message ) { CancelListen(); llSay(0, name + " picked the option '" + message + "'."); // Process Common Menu options if("Flexi" == message) HandleFlexi(id); else if("Phantom" == message) HandlePhantom(id); else if("EMERGENCY" == message) HandleEmergency(id); else if("Inside" == message) ShowInsideMenu(id); else if("Outside" == message) ShowOutsideMenu(id); else if("All" == message) ShowAllMenu(id); else if("Back" == message) ShowMainMenu(id); else if("Texture" == message) ShowTextureMenu(id); else { // Get the sub menu selection not already catered for integer selection = llListFindList(MENU_OPTIONS, [message]); if(selection != -1) { integer value = (integer)message; if(MODE_ALL == mode)HandleAll(value); else if(MODE_INSIDE == mode)HandleInside(value); else if(MODE_OUTSIDE == mode)HandleOutside(value); } else { llSay(0, name + " picked invalid option '" + llToLower(message) + "'."); } } } }
|
|
Krazzora Zaftig
Do you have my marbles?
Join date: 20 Aug 2005
Posts: 649
|
11-30-2006 09:26
Thank you Newgate Ludd for showing me that. IT actually answers a question or two I have for later but for now it confuses me a tad. Just trying to take baby steps through basicly making a script work that I really want to work. Definatly going to look these all over though before I go on. Thank you all so much. ^_^ I also hate hard coded channels BUT this was for the internal dialog system so it's not something avatars would use AND most likly something I would change from "item" to "Item".
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
11-30-2006 16:41
From: Krazzora Zaftig Thank you Newgate Ludd for showing me that. IT actually answers a question or two I have for later but for now it confuses me a tad. Just trying to take baby steps through basicly making a script work that I really want to work. Definatly going to look these all over though before I go on. Thank you all so much. ^_^ I also hate hard coded channels BUT this was for the internal dialog system so it's not something avatars would use AND most likly something I would change from "item" to "Item". Well if anything confuses you please ask. I hope my code is reasonably easy to understand, I try to write as verbosely and obviously as possible when I post here. Admittedly I didnt comment very heavily but the script is quite straight forward. I would suggest you always use a random channel with Dialogs, its invisible to the AV using the system and does make it easier for you, you never have to worry about assigning a channel number, the probability of getting two channels the same is pretty minimal. Channel = (integer)llFrand(2147483647);
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
12-01-2006 13:52
If you (can) have multiple simultaneous users, keeping a global menu context is NOT likely to be very nice for them. It is far better to have multiple channels, each of which handles a different dialog response. Then you can switch by channel number before handling the actual message string.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
12-01-2006 14:00
Pseudo-code example of what I mean by my last post: integer MAIN_MENU_CHANNEL = -1538030273; integer SUB_MENU_1_CHANNEL = -1538030274; integer SUB_MENU_2_CHANNEL = -1538030275;
string MAIN_MENU_NAME = "MainMenu"; string SUB_MENU_1_NAME = "SubMenu1"; string SUB_MENU_2_NAME = "SubMenu2";
list MAIN_MENU_CHOICES = [ SUB_MENU_1_NAME, SUB_MENU_2_NAME, "Ha ha!", ... ]; list SUB_MENU_1_CHOICES = [ MAIN_MENU_NAME, "foo", "bar", ... ]; list SUB_MENU_2_CHOICES = [ MAIN_MENU_NAME, "foobar", "barfoo", ... ];
handleDialogMessage(integer channel, key id, string message) { if (channel == MAIN_MENU_CHANNEL) { handleMainMenuMessage(id, message); } else if (channel == SUB_MENU_1_CHANNEL) { handleSubMenu1Message(id, message); } else if (channel == SUB_MENU_2_CHANNEL) { handleSubMenu2Message(id, message); } }
handleMainMenuMessage(key id, string message) { if (message == SUB_MENU_1_NAME) { displaySubMenu1(id); } else if (message == SUB_MENU_2_NAME) { displaySubMenu2(id); } else ... }
handleSubMenu1Message(key id, string message) { if (message == MAIN_MENU_NAME) { displayMainMenu(id); } else ... }
handleSubMenu2Message(key id, string message) { if (message == MAIN_MENU_NAME) { displayMainMenu(id); } else ... }
...
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
12-01-2006 14:27
From: Hewee Zetkin If you (can) have multiple simultaneous users, keeping a global menu context is NOT likely to be very nice for them. It is far better to have multiple channels, each of which handles a different dialog response. Then you can switch by channel number before handling the actual message string. Very true, I'd coded it up with the intention that it will be single user but there is indeed nothing to stop a second user from interacting with the object.
|
|
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
|
12-12-2006 23:57
From: Krazzora Zaftig Thank you Newgate Ludd for showing me that. IT actually answers a question or two I have for later but for now it confuses me a tad. Just trying to take baby steps through basicly making a script work that I really want to work. Definatly going to look these all over though before I go on. Thank you all so much. ^_^ I also hate hard coded channels BUT this was for the internal dialog system so it's not something avatars would use AND most likly something I would change from "item" to "Item". Although thast true its also best to use random channels, it just stops you from needing to keep an eye on which channels you have already assigned and will stop someone from being able to spoof your system by using a scanner to find the channel.
|