Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Conditionally triggering a menu from another object.

Iria Troell
Bunny of the House
Join date: 30 Jan 2007
Posts: 10
05-08-2007 23:44
This is more of a conceptual thing I was hoping you guys could point me to the right commands or protocol for. I imagine this is pretty basic, but every pyramid must have a strong base, neh? :)

I've created a multitool with a toolbox component on the back, and an attachment for the hand which will show whatever tool i select through a menu from the toolbox. This is all purely cosmetic, so I dont really need to worry about activating or deactivating scripts. I also have set the menu in the box to activate through a listen when you click on the hand piece, which is where I run into my problem.

For the toolbox and handpiece menu, I understand how to compare llDetectedKey to llGetOwner to avoid other people activating it. However, the command sent through listen will trigger no matter who or what says it. Basically I want ideas on how I make the menu in the toolbox only accept the command from that particular handtool that came with it, and in such a way that if another person nearby has the same item it wont activate either. Cross-chatter, etc.

CODE
 touch_start(integer total_number)
{
//Get User Key for later use in dialogs
USERKEY = llDetectedKey(0);

if(USERKEY == llGetOwner())
{
//Go to First Dialog
state GetDialog1;
}
}

listen(integer channel, string name, key id, string message)
{
if((message == "wheelmenu"))
{
state GetDialog1;
}
}


I figure llGetOwner is probably the proper way to do this as well, but can't really figure how to transmit that information along with the menu command. I mean, doing a llGetOwner would be cake on a vocal command, but how to transmit that through another script? Maybe communicating the activation command through a list with both the userkey and the command would work? I dont really understand lists yet though, so I'm a bit confused. I've seen items that have to be initialized, and key themselves to the owner and other components permanently, but thats prolly way more advanced than I need.

Anyway, any thoughts appreciated.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-09-2007 00:16
I may be misundetstanding what you are trying to do but...
Is it the object speaking or the owner via a dialog?
If it is the latter then just use the owners's key as the filter.
If its the object then you can use llGetOwnerKey and compare that with the owner's key.
_____________________
I'm back......
Anti Antonelli
Deranged Toymaker
Join date: 25 Apr 2006
Posts: 1,091
05-09-2007 00:17
llGetOwnerKey

This gets the owner of an object specified by key. And you get the key of the handtool in the listen event (key id). So:
CODE

listen(integer channel, string name, key id, string message)
{
// is the owner of (id) also the owner of this object?
if(llGetOwnerKey(id) == llGetOwner())
{
do_Stuff
}
}



That's how I'd do it anyway :)


edit: and more importantly, how Newgate would do it :p
Iria Troell
Bunny of the House
Join date: 30 Jan 2007
Posts: 10
05-09-2007 01:23
From: Newgate Ludd
I may be misundetstanding what you are trying to do but...
Is it the object speaking or the owner via a dialog?
If it is the latter then just use the owners's key as the filter.
If its the object then you can use llGetOwnerKey and compare that with the owner's key.



It is the former.

I totally understand using llGetOwnerKey for myself (or the owner) speaking or directly clicking the objects mentioned to get the dialogue menu, but I'm trying to figure out how to transmit that ownerkey through the hand attachment as a condition for listening in the toolbox to activate the dialogue menu. The listen command allows for the key of what it listening to to be a factor, but wont that be the key of the hand item instead of the owners? I want it to check for the owner of the hand attachment. I guess what im asking is what the proper way to transmit that information would be.

Basically, I want an item, activated by the owner, to communicate to another items. But since listen only will discern the key of the object speaking (not the owner of the item speaking), I need the speaking object to send that owner information in a readable format somehow along with the command so that it will only respond to the objects based on the criteria of owner, not the object itself. I think this is a problem with paradigms, It's not that I dont understand the commands or how to use them directly (maybe), its relaying them through a third party which has me stumped.

This is probably just variable play, but I'm just not seeing how to transmit the data properly. How do you check to say "Oh, hey, this value being sent is the user key, check this, and also this next value says i should activate the menu, but only if that userkey is right."

I'm just not getting it, even though it feels like it should be obvious.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-09-2007 02:08
In the example propossed the item wouldnt filter the listen, mainly because it wont know the key of the item ahead time.

If the toolbox is rezzing the attachment then it would know its key, but i think that is the opposite way around to what you are wanting. What I would do in that situation would be for the attachement to start a listen on a known channel. Then the toolbox to say on that channel the key of the attachment it just rezzed. The attachment would hear the message and check that the said key matches and then delete its current listen and start a new one filtered by the key of the toolbox (which was passed in as part of the listen).
_____________________
I'm back......
Anti Antonelli
Deranged Toymaker
Join date: 25 Apr 2006
Posts: 1,091
05-09-2007 04:07
Are you sure you didn't miss the difference between llGetOwner and llGetOwnerKey in the previous posts? I apologize if I'm misunderstanding, but when you say:

"...using llGetOwnerKey for myself (or the owner) speaking or directly clicking the objects..."

you're describing the way llGetOwner is usually used, not the way llGetOwnerKey works.


There's no reason to transmit keys ahead of time and set up listen filters. Just do what you've been doing, and take another look at the snippet I posted before - it tests if the transmitting object (the tool) has the same owner as the receiving object (the box). If they are both owned by you, stuff happens. If the owners are different (as when someone else is using their tool nearby), nothing happens.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-09-2007 04:17
From: Anti Antonelli
Are you sure you didn't miss the difference between llGetOwner and llGetOwnerKey in the previous posts? I apologize if I'm misunderstanding, but when you say:

"...using llGetOwnerKey for myself (or the owner) speaking or directly clicking the objects..."

you're describing the way llGetOwner is usually used, not the way llGetOwnerKey works.


There's no reason to transmit keys ahead of time and set up listen filters. Just do what you've been doing, and take another look at the snippet I posted before - it tests if the transmitting object (the tool) has the same owner as the receiving object (the box). If they are both owned by you, stuff happens. If the owners are different (as when someone else is using their tool nearby), nothing happens.


The only reason for adding the listen filter is to 'tighten' it up a bit more but as we have both said its not actually required although it should in theory be more efficient.
_____________________
I'm back......
Iria Troell
Bunny of the House
Join date: 30 Jan 2007
Posts: 10
05-09-2007 16:39
Actually, thats exactly what i needed, thanks Anti :)
Iria Troell
Bunny of the House
Join date: 30 Jan 2007
Posts: 10
05-10-2007 11:49
Alright, I'm having another problem, this time in the tool portion in the hand.

The listen area is where it all falls apart. I need to have message identify itself as the relevant variable and have that particular variable changed to TRUE or FALSE.

CODE
key USERKEY = NULL_KEY;

//This is to keep track of what is out and vanish the tool base if none of the 8 attachments are out.
integer x;

integer Item1 = FALSE;
integer Item2 = FALSE;
integer Item3 = FALSE;
integer Item4 = FALSE;
integer Item5 = FALSE;
integer Item6 = FALSE;
integer Item7 = FALSE;
integer Item8 = FALSE;

default
{
state_entry()
{
llListen(258, "", "", "");
}

touch_start(integer total_number)
{
USERKEY = llDetectedKey(0);

if(USERKEY == llGetOwner());
{
llWhisper(258, "wheelmenu");
}
}

listen(integer channel, string name, key id, string message)
{
if(llGetOwnerKey(id) == llGetOwner())
{
if((message == "Reset"))
{
Item1 = FALSE;
Item2 = FALSE;
Item3 = FALSE;
Item4 = FALSE;
Item5 = FALSE;
Item6 = FALSE;
Item7 = FALSE;
Item8 = FALSE;
llSetAlpha(0.0, ALL_SIDES);
}

//here comes the gibberish

else if((message == ("Item" + (x))
{
if((Item + (x)) == TRUE)
{
(Item + (x)) = FALSE;
}
else if((Item + (x)) == FALSE)
{
(Item + (x)) = TRUE;
}
}


//I need to have message identify itself as the relevant variable and have that particular variable set to TRUE or FALSE. //When all are false, tool base disappears.

}
}
}
Milambus Oh
Registered User
Join date: 6 Apr 2007
Posts: 224
05-10-2007 13:38
You are missing several closing parentheses in your else statement.

Try:
CODE

//here comes the gibberish

else if(message == ("Item" + (x)))


I don't believe that interpretive commands like the following will work in LSL:
CODE
(Item + (x)) = FALSE;


Instead you will need to use a List, something like this...

CODE

key USERKEY = NULL_KEY;

//This is to keep track of what is out and vanish the tool base if none of the 8 attachments are out.
integer x;

// Using a list now
list items = [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE];

default
{
state_entry()
{
llListen(258, "", "", "");
}

touch_start(integer total_number)
{
USERKEY = llDetectedKey(0);

if(USERKEY == llGetOwner());
{
llWhisper(258, "wheelmenu");
}
}

listen(integer channel, string name, key id, string message)
{
if(llGetOwnerKey(id) == llGetOwner())
{
if((message == "Reset"))
{
items = [FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE];
llSetAlpha(0.0, ALL_SIDES);
} else if(llLowerCase(llGetSubString(0, 6)) == "message") // Parsing out the first 7 chars
{
// This is the number they entered
integer num = (integer)llGetSubString(6, -1);

if(llList2Integer(items, num) == TRUE)
{
items = llListReplaceList(items, [TRUE], num, num);
}
else // Things should be true or false, no need to waste CPU...
{
items = llListReplaceList(items, [FALSE], num, num);
}
}


//I need to have message identify itself as the relevant variable and have that particular variable set to TRUE or FALSE. //When all are false, tool base disappears.

}
}
}
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-10-2007 15:55
I'm obviously missing the point here, but if the tool box only allows one item to be active / selected at a time (i.e. you can only hold one in your hand) why use boolean flags rather than a numeric index?
_____________________
I'm back......
Iria Troell
Bunny of the House
Join date: 30 Jan 2007
Posts: 10
05-10-2007 16:44
Well, it's because I understand boolean, and don't really know what you mean by a numeric index.

When I envision this I think of it like a circuit breaker with separate on-off switches for each attachment. I'm not really sure how you see it.

I mean, from what you are saying this isnt the best method or logical, but i'm still ignorant and working with what I have.

Milambus, a list, eh? I'd never seen that substring command before either, thats really useful.
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
05-11-2007 00:17
From: Iria Troell
Well, it's because I understand boolean, and don't really know what you mean by a numeric index.

When I envision this I think of it like a circuit breaker with separate on-off switches for each attachment. I'm not really sure how you see it.

I mean, from what you are saying this isnt the best method or logical, but i'm still ignorant and working with what I have.

Milambus, a list, eh? I'd never seen that substring command before either, thats really useful.


Ok, my understanding of your situatrion is that you have 9 integers (your boolean flags) which you are using to switch between your items. But since you can only have one active at a time you could just as easily use a numeric variable as an index or state value.

your code will look something like this

if(flag1) DoA();
else if(flag2) DoB();
else if .........

mine would be

if(constItemA == index)DoA();
else if(constItemB == index)DoB();
else if ......

Its simpler logic and uses less memory
_____________________
I'm back......