Jump to content

Using dialogue box to resize multiple prims


You are about to reply to a thread that has been inactive for 1367 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

I'm new to scripting so I'm not really sure what the best way to do this is. I'm trying to make a resize script for a pair of boots, but can only find examples of scripts that resize link sets. I have a llDialog and llListen function set up so that I can resize the boots and also return them to the default size. I copied the same script into the other boot so they are both listening to the same channel. When I click on one of the boots it resizes as expected but the other boot remains the same size. Is there a function so that they both react to the same function when an option is selected from the Dialog menu? 

 

Any help would be appreciated :)

Link to post
Share on other sites

Without being being able to see the script it's a bit of a guessing game, but I strongly suspect, from what you say, that the resize scripts open a listener when you touch them to open the dialog menu.   That's standard (and good) practice.   However, it means that only the boot you touch is going to hear the message.

I think the way I would do it is to have two separate channels, one for the dialog menu, which opens and closes the listener when the boot is touched and when it receives a dialog message, and a separate channel (very negative) on which the boots listen all the time.  The effect on the region of keeping a listener open on a channel that's used only by one pair of scripts will be negligible. 

Then, when you hear a reply from the dialog menu, have the dialog script repeat it, on the channel that's open all the time, using llRegionSayTo(OwnerUUID,,BootsChannel, message).

The reason I would use llRegionSayTo is that when you use it to send a message to an agent, scripts in objects the agent is wearing (or sitting on) can hear it, too, provided they're listening on that channel.   So you don't have to worry about your boots receiving messages intended for someone else.

I hope that's clear.  If not, please say and I'll post a bit of code to clarify when I mean.

ETA:  ChinRey and I posted at the same time.  Let me clarify my thinking on open listeners.   

The reason open listeners can be (not are, necessarily) bad is that when the simulator hears a message, it checks first to see which scripts are listening on the channel on which the message is sent, then if the objects listening on that channel are within range, then, if they are, if the message passes the filters set in the listener, and then the scripts that can hear the message have to decide what, if anything, to do about it.

That's potentially a lot of work, but if only one pair of scripts on the region is using that channel (which will almost always be the case if you use a negative number 7 or 8 digits long) then it's not really causing the simulator to do much.

Furthermore, or at least as I understand it, llRegionSayTo circumvents a lot of these checks, in that the simulator has simply to check the recipient is on the region and then to check if the recipient is wearing anything (or sitting on anything) that is listening on that channel.

So, all in all, using the method I suggest isn't going to cause the simulator appreciably more work than would resizing the boots separately.

As far as I'm concerned, the rule is "Don't keep listeners open without a good reason" rather than "Don't ever have open listeners".

 

Edited by Innula Zenovka
  • Like 4
Link to post
Share on other sites

I agree with the above; I have several items that actually sort of need to keep a listener open in order to work at all. If it isn't listening, it won't hear what it needs to hear when it needs to hear it, after all. I do think that until one understands the whys and whens as well as the hows it's good practice to follow some sort of somewhat hard and fast rules, but once you get why the rules exist (to prevent the inexperienced from destroying the virtual universe, lol), and you know more what you're doing, they're really more like guidelines...

I don't really see where it's any big deal to have a listen running in a resizer script, myself. You put the boots on, you resize them, you clean up the script and save a copy in case you need it again. As far as lag is concerned, one good 1024 x 1024 Hi-Def texture on an eyeball probably produces more than having a lonely little listen open on an obscure negative channel.

If anything, a listen remove before the llDie() in the script cleanup option would be the thing, just in case. You do have a script cleanup option, right? xD

Edited by Berksey
  • Like 1
Link to post
Share on other sites

Thank you for your responses. 

 

I think I understand what you are saying Innula about to create a separate listen. I'll have a look on the LSL portal and see if I can work something out otherwise do you mind if I send you a PM to clarify further if I run into trouble? 

 

Berksey, I'm a complete noob when it comes to scripting actually xD I hadn't thought of adding a script clean-up option but have included a listen remove. From what I understand from the wiki adding the llDie() will delete the script but not the attachment itself whilst it is attached? Tbh I was hoping to sell the boots once I had worked out how to create a stable resizer so I'm not sure if it would be a good option for customers if they weren't able to resize them again after purchase, though at the same time I wouldn't want to have any unnecessary lag caused by them. I hope I've understood what you were trying to say correctly. 

 

Here is a copy of the script without the changes suggested by Innula:

 

integer dialoglistener;
vector DefaultSize = <0.279,0.146,0.589>;

default
{
    state_entry()
    {

    }

    touch_start(integer total_number)
    {
      dialoglistener = llListen(16584,"","","");
        llDialog(llGetOwner(), "Select an option", ["Default","+0.1","+0.05","+0.01","-0.1","-0.05","-0.01"], 16584);
    }

    listen (integer channel, string name, key id, string message)
    {
        if(channel==16584) {
        if (message == "Default")
        {
            llSetScale(DefaultSize);
        }
              else if(message == "+0.1")
            {
                 llScaleByFactor(1.1);
            }
             else if(message == "+0.05")
            {
                 llScaleByFactor(1.05);
            }
             else if(message == "+0.01")
            {
                 llScaleByFactor(1.01);
            }
            else if(message == "-0.1")
            {
                 llScaleByFactor(0.9);
            }
             else if(message == "-0.05")
            {
                 llScaleByFactor(0.95);
            }
              else if(message == "-0.01")
            {
                 llScaleByFactor(0.99);
            }
            
            llListenRemove(dialoglistener);
        }
}
}

 

Link to post
Share on other sites
1 hour ago, buubbleguum Emerald said:

From what I understand from the wiki adding the llDie() will delete the script but not the attachment itself whilst it is attached?

Nope.   To remove the script, while leaving the attachment intact, you want

 llRemoveInventory(llGetScriptName());

("Find an item in the object's inventory with the same name as this script, and remove it").

Here's a fragment showing how I would handle the two listeners.   You have to add your own dialog box and handle the resizing.   Note that the boot generating the dialog and sending the llRegionSayTo message won't hear the message it sends.   That's why you have to resize it when the script it contains hears the dialog message.

integer iBootsChannnel = -60195592;//change this to some other random integer of your choice
integer iDialogChannel = -40598940;//again, change this.  
//You could generate a random channel each time you open a dialog 
//but since you listen only to the boots' owner, I don't think that's necessary here.
integer iHandle;

key kOwner;

default {
	state_entry() {
		llListen(iBootsChannnel,"","","");
		kOwner = llGetOwner();
	}

	attach(key id) {
		if(id){
			kOwner = id;
		}
	}

	touch_start(integer num_detected) {
		llListenRemove(iHandle);
		iHandle = llListen(iDialogChannel,"",kOwner,"");
		//present the dialog menu
		llDialog(kOwner, "Some message", ["A Button","Another Button"], iDialogChannel);
		
	}

	listen(integer channel, string name, key id, string message) {
		if(iDialogChannel == channel){
			llListenRemove(iHandle);
			llRegionSayTo(kOwner,iBootsChannnel,message);
			llOwnerSay("heard "+message+" on the dialog channel");
			//and do stuff resize this boot -- the boot that was touched
		}
		else if (iBootsChannnel == channel){
			//do stuff to resize this boot -- the boot that wasn't touched
			llOwnerSay("heard "+message+" on the boots channel");
		}
	}
}

Message me if you want to, but I'd rather answer questions here so that other people who may find this thread in the future can see the questions and answers.    When I first started scripting, I found reading old threads really helped me understand how things work, since people were asking the same questions I wanted to about parts of example scripts I didn't understand.

Edited by Innula Zenovka
  • Like 3
Link to post
Share on other sites

Innula's schematic approach is what I would suggest myself.  Since we're focusing on good practice in scripting dialog, though, I would add one more useful component, a timeout provision.  This is important for a couple of reasons.  First, if the script will be used by several people (say, for example, in a vendor script), you'll need some way to be sure that a second user cannot accidentally give responses that the script will think were made by the first user.  Second, a script that is waiting for a user response can stall  -- locked, waiting for input -- if the user walks away without responding. Even if neither of those things happens, a timeout provision is good practice simply because it cleans up loose ends.  In my opinion, it is always useful to anticipate possible ways that a user can screw up and get there first.  That saves user frustration and avoids customer service calls.

My modification of Innula's script would look something like this:



integer iBootsChannnel = -60195592;//change this to some other random integer of your choice
integer iDialogChannel = -40598940;//again, change this.  
//You could generate a random channel each time you open a dialog 
//but since you listen only to the boots' owner, I don't think that's necessary here.
integer iHandle;

key kOwner;

default {
	state_entry() {
		llListen(iBootsChannnel,"","","");
		kOwner = llGetOwner();
	}

	attach(key id) {
		if(id){
			kOwner = id;
		}
	}

	touch_start(integer num_detected) {
		llListenRemove(iHandle);
		iHandle = llListen(iDialogChannel,"",kOwner,"");
		//present the dialog menu
		llDialog(kOwner, "Some message", ["A Button","Another Button"], iDialogChannel);
		llSetTimerEvent(15.0);    // Start your timer here, giving the user 15 seconds to respond ...		
	}

    timer() {
        llListenRemove(iHandle);    // Close the dialog channel
        llOwnerSay("Timeout. Please close the dialog box on your screen.");   // Optional but friendly
        llSetTimerEvent(0.0);    // Close the timer
    }
 

	listen(integer channel, string name, key id, string message) {
		if(iDialogChannel == channel){
    		llSetTimerEvent(0.0);    // Turn off the timeout timer here too
			llListenRemove(iHandle);
			llRegionSayTo(kOwner,iBootsChannnel,message);
			llOwnerSay("heard "+message+" on the dialog channel");
			//and do stuff resize this boot -- the boot that was touched
		}
		else if (iBootsChannnel == channel){
			//do stuff to resize this boot -- the boot that wasn't touched
			llOwnerSay("heard "+message+" on the boots channel");
		}
	}
}

[Click and drag to move]

 

Edited by Rolig Loon
Script formatting
  • Like 3
Link to post
Share on other sites

Oh, beautiful stuff, everyone! And Nova, I love stuff like that, too! I'm just not good at it yet myself, lol.

And yeah, llDie() wasn't the best thingy to throw out there for that particular instance, forgive me. I might not have had enough coffee to remember you weren't deleting an object but a script in my hypothetical thingywatser... <-<; Can you tell I'm kinda new to this too?

^-^;

  • Like 1
Link to post
Share on other sites
On 2.6.2017 at 0:30 AM, Berksey said:

And yeah, llDie() wasn't the best thingy to throw out there for that particular instance, forgive me. I might not have had enough coffee to remember you weren't deleting an object but a script in my hypothetical thingywatser... <-<; Can you tell I'm kinda new to this too?

I once confused llDie and llRemoveInventory and made a stupid face. Either not enough or too much coffee. :D

Link to post
Share on other sites

Sorry for the delayed response, I've had a crazy week this week. When I logged on today, the script I posted worked and resized both the boots. I'm guessing that perhaps the prims just needed to reset. However, I'm still grateful that I posted and for all your responses as I can now make sure I'm using the best practice and make them as user-friendly as possible. 

On 6/1/2017 at 11:17 PM, Innula Zenovka said:

 

Here's a fragment showing how I would handle the two listeners.   You have to add your own dialog box and handle the resizing.   Note that the boot generating the dialog and sending the llRegionSayTo message won't hear the message it sends.   That's why you have to resize it when the script it contains hears the dialog message.

Message me if you want to, but I'd rather answer questions here so that other people who may find this thread in the future can see the questions and answers.    When I first started scripting, I found reading old threads really helped me understand how things work, since people were asking the same questions I wanted to about parts of example scripts I didn't understand.

3

Thank you so much Innula for taking the time to help me out :) I've tested out the script and it works beautifully.

 

On 6/1/2017 at 11:17 PM, Innula Zenovka said:

Message me if you want to, but I'd rather answer questions here so that other people who may find this thread in the future can see the questions and answers.    When I first started scripting, I found reading old threads really helped me understand how things work, since people were asking the same questions I wanted to about parts of example scripts I didn't understand.

 

Understand completely, the forum has been a huge help.

 

On 6/1/2017 at 11:44 PM, Rolig Loon said:

Innula's schematic approach is what I would suggest myself.  Since we're focusing on good practice in scripting dialog, though, I would add one more useful component, a timeout provision.  This is important for a couple of reasons.  First, if the script will be used by several people (say, for example, in a vendor script), you'll need some way to be sure that a second user cannot accidentally give responses that the script will think were made by the first user.  Second, a script that is waiting for a user response can stall  -- locked, waiting for input -- if the user walks away without responding. Even if neither of those things happens, a timeout provision is good practice simply because it cleans up loose ends.  In my opinion, it is always useful to anticipate possible ways that a user can screw up and get there first.  That saves user frustration and avoids customer service calls.

My modification of Innula's script would look something like this:

 

2

Thank you very much for the advice otherwise I would have overlooked this. Will definitely be keeping this in mind for future listeners.

 

On 6/2/2017 at 8:30 AM, Berksey said:

Oh, beautiful stuff, everyone! And Nova, I love stuff like that, too! I'm just not good at it yet myself, lol.

And yeah, llDie() wasn't the best thingy to throw out there for that particular instance, forgive me. I might not have had enough coffee to remember you weren't deleting an object but a script in my hypothetical thingywatser... <-<; Can you tell I'm kinda new to this too?

^-^;

hehe no worries xD hopefully we'll both be confident scripters in no time

Link to post
Share on other sites
You are about to reply to a thread that has been inactive for 1367 days.

Please take a moment to consider if this thread is worth bumping.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...