Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Too many else's in my first dialog script???

Bill Schmo
Registered User
Join date: 16 Aug 2006
Posts: 53
07-29-2007 20:14
First I'd like to say thanx for reading this, if it wasnt for helpful ppl i wouldnt understand any of this stuff :)

I created an object that needed a very large dialog menu. no matter what i did i was gettin a sytax error, then i learned it was b/c i had too many else's. so i read the wiki and find out that there is a limit of 23 ( else's ) and 24 if i add an ( if ) and the wiki suguested to "nest". so nesting/grouping i tried.. this way, that way and nothing worked out. so here i am after 2 nights of addin this and removing that.. i would love to learn to do this, but i learn from example and an "Example: 30 Option Multi-level Dialog Script" doesnt exist, or at least i cant find it. i was only creating this as an example for me to use as a refrence, and i know there are better ways of codeing a "Roach Coach", lol

like i said i have removed, added, and re-written this a few times so, at this point i dont really know whats in there that should or shouldnt be, lol

ok, no matter what i do it chokes right after i select the topping, and never announces the llSay(0, "_____ with _____";) message.

From: someone


integer CHANNEL = 123456;
integer DialogCHANNEL = 654321;

list MENU_MAIN = ["Hamburger", "Salad", "Pizza", "Ice Cream", "Hot Dog"];
list HAMBURGER_OPTIONS = ["Lettice", "Pickle", "Tomato", "Cheese", "...Back"];
list SALAD_OPTIONS = ["French", "Ranch", "Ceaser", "Thousand Island", "Plain", "...Back"];
list PIZZA_OPTIONS = ["Ham", "Pineapple", "Bacon", "Xtra Cheese", "...Back"];
list ICECREAM_OPTIONS = ["Sprinkles", "Nuts", "Hot Fudge", "Cherry", "Bannana", "Wip Cream", "...Back"];
list HOTDOG_OPTIONS = ["Ketchup", "Mustard", "Relish", "Onion", "Chili", "...Back"];

default
{
state_entry()
{
llListen(DialogCHANNEL, "", NULL_KEY, "";);
}

touch_start(integer total_number)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}

listen(integer DialogCHANNEL, string name, key id, string message)
{
if (llListFindList(MENU_MAIN, [message]) != -1)
{
if (message == "Hamburger";)
{
llDialog(id, "What topping would you like on your burger?\nYou only get one!", HAMBURGER_OPTIONS, DialogCHANNEL);
{
if (message == "Lettice";)
{
llSay(0, "Hamburger with Lettice";);
}

else if (message == "Pickle";)
{
llSay(0, "Hamburger with Pickle";);
}

else if (message == "Tomato";)
{
llSay(0, "Hamburger with Tomato";);
}

else if (message == "Cheese";)
{
llSay(0, "Hamburger with Cheese";);
}

else if (message == "Pickle";)
{
llSay(0, "Hamburger with Pickle";);
}

else if (message == "Pickle";)
{
llSay(0, "Hamburger with Pickle";);
}

else if (message == "...Back";)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}
}
}
}

if (llListFindList(SALAD_OPTIONS, [message]) != -1)
{
if (message == "Salad";)
{
llDialog(id, "What dressing would you like on your salad?\nYou only get one!", SALAD_OPTIONS, DialogCHANNEL);
{
if (message == "French";)
{
llSay(0, "Salad with French";);
}

else if (message == "Ranch";)
{
llSay(0, "Salad with Ranch";);
}

else if (message == "Ceaser";)
{
llSay(0, "Salad with Ceaser";);
}

else if (message == "Thousand Island";)
{
llSay(0, "Salad with Thousand Island";);
}

else if (message == "Plain";)
{
llSay(0, "Salad with Plain";);
}

else if (message == "...Back";)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}
}
}
}

if (llListFindList(PIZZA_OPTIONS, [message]) != -1)
{
if (message == "Pizza";)
{
llDialog(id, "What topping would you like on your pizza?\nYou only get one!", PIZZA_OPTIONS, DialogCHANNEL);
{
if (message == "Ham";)
{
llSay(0, "Pizza with Ham";);
}

else if (message == "Pineapple";)
{
llSay(0, "Pizza with Pineapple";);
}

else if (message == "Bacon";)
{
llSay(0, "Pizza with Bacon";);
}

else if (message == "Xtra Cheese";)
{
llSay(0, "Pizza with Xtra Cheese";);
}

else if (message == "...Back";)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}
}
}
}

if (llListFindList(ICECREAM_OPTIONS, [message]) != -1)
{
if (message == "Ice Cream";)
{
llDialog(id, "What topping would you like on your ice cream?\nYou only get one!", ICECREAM_OPTIONS, DialogCHANNEL);
{
if (message == "Sprinkles";)
{
llSay(0, "Ice Cream with Sprinkles";);
}

else if (message == "Nuts";)
{
llSay(0, "Ice Cream with Nuts";);
}

else if (message == "Hot Fudge";)
{
llSay(0, "Ice Cream with Hot Fudge";);
}

else if (message == "Cherry";)
{
llSay(0, "Ice Cream with a Cherry";);
}

else if (message == "Bananna";)
{
llSay(0, "Ice Cream with Bananna";);
}

else if (message == "Wip Cream";)
{
llSay(0, "Ice Cream with Wip Cream";);
}

else if (message == "...Back";)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}
}
}
}

if (llListFindList(HOTDOG_OPTIONS, [message]) != -1)
{
if (message == "Hot Dog";)
{
llDialog(id, "What topping would you like on your hotdog?\nYou only get one!", HOTDOG_OPTIONS, DialogCHANNEL);
{
if (message == "Ketchup";)
{
llSay(0, "Hot Dog with Ketchup";);
}

else if (message == "Mustard";)
{
llSay(0, "Hot Dog with Mustard";);
}

else if (message == "Relish";)
{
llSay(0, "Hot Dog with Relish";);
}

else if (message == "Onion";)
{
llSay(0, "Hot Dog with Onion";);
}

else if (message == "Chili";)
{
llSay(0, "Hot Dog with Chili";);
}

else if (message == "...Back";)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}
}
}
}
}
}

Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
07-29-2007 21:09
/me takes away Bill's { and } keys!

One thing you can do is lose most of the "else"s and put a return in whenever you know that you're not going to have to do anything more in that listen function..

Instead of

if (something)
{
stuff;
}
else if (somethingElse)
{
other stuff;
}
else ...

Do

if (something)
{
stuff;
return;
}

if (somethingElse)
{
otherStuff;
return;
}

Once you fix that, you're going to still have problems with your dialogs. A dialog response is always done in chat so you can't call llDialog in the middle of a function and get the result right there - you have to wait for the next call into your listen handler.

Another option to your "else" issue would be to have a set of lists that define the words you're looking for and their responses.. Maybe

list HOTDOG_OPTIONS = ["Ketchup", "Mustard", "Relish", "Onion", "Chili", "...Back"];
list HOTDOG_REPLIES = ["Hot Dog with Ketchup", "Hot Dog with Mustard", "Hot Dog with Relish", "Hot Dog with Onion", "Hot Dog with Chili"];

Once you find the index of the dialog message in HOTDOG_OPTIONS, display that same index into HOTDOG_REPLIES.
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
07-29-2007 21:17
You are testing if the message is contained within an existing list of possible choices to determine which type of item it is (hamburger, salad, pizza, etc.), then using an inefficient if-else chain just to prepend that item classification on a string which repeats the original received message.

Replace your long chains of:

else if( message == "something" )
llSay( 0, "whatever with something" );

with a single:

llSay( 0, "whatever with " + message );
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
07-29-2007 23:35
as hinted above ask if you really need all those clauses, if its a YES then you can enbed them

ie

if (message == "a" || message == "b";)
{
if (message == "a";) do a's stuff
else do b's stuff
}

that will cut your clauses in half, altho your increasing your processing time becuase your now asking 3 questions (if a, if b and if a again)

you can only do 2 at a time but you can group them here i do 3, but in reality theres only 2 values considered here

if ( (message == "a" || message == "b";) || message == "c";)

or for 4

if ( (mes == "a" || mes == "b";) || (mes == "c" || mes == "d";) )

you can only have (what 32?) so many in 1 tree, but another 32 under that tree and so on and so on ... after a while it starts to really screw up tho, (probally around 96 total clauses?) so you really should figure out how to optimise your structure

even indexing a list of possible awnsers would be more effecient VS a crapton of IF clauses

ie

list bob = ["apple","orange","hotdog","pizza","hamburger","nachos"]

state whatever
{
event here(event options)
{
integer index = llListFindList(bob,[message];
if (index < 3)
{
if (index == 0) apples;
else if (index == 1) oranges;
else hotdogs;
}
ect
}
}
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
07-30-2007 02:12
This is one place where LSL is really weak. In lieu of a case statement, the parallel (or strided) lists approach Sindy recommends is very powerful--but soon enough one longs for function pointers, a computed goto, or some desperate means of branching execution from those lists.

One approximation is to llMessageLinked an integer token from the list lookup, with separate scripts triggered by their specific tokens to perform the conditional processing--but that's only sometimes viable (delay, segmentation of state variables, code complexity, etc.).
Shadow Subagja
Registered User
Join date: 29 Apr 2007
Posts: 354
07-30-2007 11:04
I would agree with most of whats been said as well. I do see the potential to use states (I am a bit of a state-junky though). If I were to do that I might do something like address the main menu, then switch to the appropriate state for creating each food dish. Each of those states could present its table of selections and potentially even add some additional flare since you would be in a specific state so you could now do 'salad making only' behaviors etc. You get that for free with states, so it is fun to abuse.

Maybe something like this (note only a demonstration of concept, I didn't fully rewrite it.. )

integer CHANNEL = 123456;
integer DialogCHANNEL = 654321;

list MENU_MAIN = ["Hamburger", "Salad", "Pizza", "Ice Cream", "Hot Dog"];
list HAMBURGER_OPTIONS = ["Lettice", "Pickle", "Tomato", "Cheese", "...Back"];
list SALAD_OPTIONS = ["French", "Ranch", "Ceaser", "Thousand Island", "Plain", "...Back"];
list PIZZA_OPTIONS = ["Ham", "Pineapple", "Bacon", "Xtra Cheese", "...Back"];
list ICECREAM_OPTIONS = ["Sprinkles", "Nuts", "Hot Fudge", "Cherry", "Bannana", "Wip Cream", "...Back"];
list HOTDOG_OPTIONS = ["Ketchup", "Mustard", "Relish", "Onion", "Chili", "...Back"];

integer listen_id;
integer RE_PRESENT_MAIN_MENU=FALSE;

default
{
state_entry()
{
listen_id=llListen(DialogCHANNEL, "", NULL_KEY, "";);
if(RE_PRESENT_MAIN_MENU == TRUE)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
RE_PRESENT_MAIN_MENU = FALSE;
}
}

touch_start(integer total_number)
{
llDialog(llGetOwner(), "What would you like?", MENU_MAIN, DialogCHANNEL);
}

listen(integer DialogCHANNEL, string name, key id, string message)
{
if ( message == "Hamburger" )
{
llListenRemove(listen_id);
state burger;
}
else if ( message == "Salad" )
{
llListenRemove(listen_id);
state salad;
}
else if ( message == "Pizza" )
{
llListenRemove(listen_id);
state Pizza;
}
else if ( message == "Ice Cream" )
{
llListenRemove(listen_id);
state IceCream;
}
if ( message == "Hot Dog" )
{
llListenRemove(listen_id);
state HotDog;
}
}
}
}


state burger
{
state_entry()
{
listen_id = llListen(DialogCHANNEL, "", NULL_KEY, "";);
llDialog(id, "What topping would you like on your burger?\nYou get as many as you like!!", HAMBURGER_OPTIONS, DialogCHANNEL);
}

listen(integer DialogCHANNEL, string name, key id, string message)
{
if ( message == "Lettuce" )
{
llSay(0, "Hamburger with Lettuce";);
llDialog(id, "What additional topping would you like on your burger?\nYou get as many as you like!", HAMBURGER_OPTIONS, DialogCHANNEL);
}
if ( message == "...Back" )
{
llListenRemove(listen_id);
RE_PRESENT_MAIN_MENU = TRUE;
state default;
}
}
}
}
Chaz Longstaff
Registered User
Join date: 11 Oct 2006
Posts: 685
08-22-2007 20:29
I think I've discovered a problem with the state approach, Shadow Subagja.

If, while in the hamburger state, the user presses Ignore on the menu, then the menu / script just gets hung in the hamburger state, and the script has to be reset to fire up the menu again.
Kidd Krasner
Registered User
Join date: 1 Jan 2007
Posts: 1,938
08-22-2007 20:38
From: Qie Niangao
This is one place where LSL is really weak. In lieu of a case statement, the parallel (or strided) lists approach Sindy recommends is very powerful--but soon enough one longs for function pointers, a computed goto, or some desperate means of branching execution from those lists.

Egads! Holy FORTRAN, Batman.

It's 2007. If Perl and Python can retrofit object-orientation, so can LSL. I can't imagine going first to computed gotos. Function pointers are a bit more arguable, but I'd rather go all the way.
Shadow Subagja
Registered User
Join date: 29 Apr 2007
Posts: 354
08-23-2007 08:17
From: Chaz Longstaff
I think I've discovered a problem with the state approach, Shadow Subagja.

If, while in the hamburger state, the user presses Ignore on the menu, then the menu / script just gets hung in the hamburger state, and the script has to be reset to fire up the menu again.



Yes this is an issue. You can however protect against it. When I write code in this way I add touch_start events to each state which jump back to the default state. You can also use timers to 'timeout' the current request and jump back to the default state. Both of these are valuable not only if the user presses cancel, but if they wander off or crash in the middle of an order as well.