Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

llDialog ONLY from Touch_Start?

Synthia Gynoid
PRIMAL DREAMS
Join date: 10 Jul 2007
Posts: 52
06-12-2008 07:52
I'm working on a script that can call up various particle effects based on menu button selections, but the number of total selections I'd like to use exceeds the maximum number of consecutive chained "else if" statements. Each menu selection in my script sends a different message to the linkset. My problem is that because of the limit to the number of chained "else if"s, I need to do something like have the script use different states or something to break up the workload. For example, like having the main menu have a "Fire" button, which takes the script to a "state Fire" state, with its own chain of "else if" statements for various fire particle effects.

Okay, my problem is that this doesn't appear to be possible. When I try something like that, as soon as the script goes into another state it forgets who touched it in the first place. It forgets who "id" is, and won't respond any further. Yes, I can have the "Fire" state (just to keep using my example) listen on CHANNEL, and respond to whatever selection is picked with the appropriate response.... but that's all it will do; it won't go "Back" to a previous menu, it won't go to any further submenus I make from that state, or anything. It's hung, non-responsive, silent, inert, from that point on until I reset the script.

How do I do what it is I'm trying to do? The problem seems to be that the script 'forgets' who touched it in the first place, which seems to suggest that you can start a llDialog only from a single touch_start event and by no other means. Is this true? Is there a workaround?

Thanks! :)
Winter Ventura
Eclectic Randomness
Join date: 18 Jul 2006
Posts: 2,579
06-12-2008 08:22
Establish that your "lasttoucher" key variable is in the largest scope, outside the default state. The variable can then be called (or defined) from any state.

CODE

key lasttoucher;

default
{

touch_start(integer num_detected)
{
lasttoucher = llDetectedKey(0);
}

}

statetwo()
{

touch_start(integer num_detected)
{
lasttoucher = llDetectedKey(0);
}

}
_____________________

● Inworld Store: http://slurl.eclectic-randomness.com
● Website: http://www.eclectic-randomness.com
● Twitter: @WinterVentura
Johan Laurasia
Fully Rezzed
Join date: 31 Oct 2006
Posts: 1,394
06-12-2008 11:38
You can, but dont need multiple states. If you do, you must re-setup the listen in each states state_entry. Personally, I wouldn't use multiple states, I would just have multiple menus. I'm not seeing your script posted here, but why would you have multiple else's in the first place?

I would simply do...
CODE

listen (integer channel, string name, key id, string message)
{
if (message == "choice 1")
{
// set particle system params and call particle system...
}

if (message == "choice 2")
{
// set particle system params and call particle system...
}

if (message == "choice 3")
{
// set particle system params and call particle system...
}
}


etc... if the total number of choices exceeds 12 (the button max), then make >> and << buttons, and call secondary, tertiary, etc.. menus, and program the >> and << buttons to call those menus. Note, I have no else's in my script.


http://www.secondscripter.com/
_____________________
My tutes
http://www.youtube.com/johanlaurasia
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
06-12-2008 11:42
From: Synthia Gynoid
My problem is that because of the limit to the number of chained "else if"s, I need to do something like have the script use different states or something to break up the workload.
Just to offer a completely different approach. :)

Given a list of the particle commands coming from llDialog (there may be other commands like menu navigation too but that's a separate issue)...

list pCommands = ["Nova", "Star Burst", "Rocket"],

You can do this in the listen...

//menu navigation first
if (message == "Main Menu";)
:
else if (message == "Fire Menu";)
:
// and finally the particles
else
{
integer i = llListFindList(pCommands, [message]);
if (i <> -1) // particle code
:
else // I give in
}

...you now have an index value for the button that was pressed...

The trick then is to call a SINGLE function that can execute the desired llParticleSystem arrangement based on that index value. This may involve extracting parameters from several other lists. The point is that sooner or later: if, elseif, elseif... just isn't going to cut it and you have to find a way to create scalable code. I'm not convinced that states offer a scalable solution.

At worst you could simply have many scripts contacted using llMessageLinked that trigger according to their matching index value...

llMessageLinked(LINK_THIS, i, "", NULL_KEY)

link_message(integer sender_num, integer num, string str, key id)
{
if (num == 1) // that's me!
{
llParticleSystem([...
}
}
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
06-12-2008 16:23
Hmm. Can you break up the else-ifs like this?

CODE

if (condition1)
{
} else if (condition2)
{
} else
{
if (condition3)
{
} else if (condition4)
{
} else
{
if (condition5)
{
} else if (condition6)
{
} else
{
}
}
}
Synthia Gynoid
PRIMAL DREAMS
Join date: 10 Jul 2007
Posts: 52
Thanks!
06-15-2008 13:06
Omg everybody thank you so much for your help! :D

The option I went with is to consolidate all my alternate outcomes into one state, and just use "if" instead of "else if". I'm not sure why I thought you had to use "else if", but I did... lol, that's what self-teaching gets you. :)
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
06-15-2008 14:30
well its better to in most situations (im not going to tell you to rewrite it now that you have it going)

if you just use if's every time that event comes up it will test all the ifs no matter if it already found an answer or not

whereas using else ifs it will test the first if, and that result is false it will move to the first else if, and so on untill it finds a clause that results in true and stop testing