Jump to content

help me out with a script? (lists & vectors question)


Sylvia Wasp
 Share

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

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

Recommended Posts

Hello, 

I'm trying to write a script that makes an object rez a bunch of items from it's own inventory at various specific locations around itself.  I have all the off-sets and rotations for these objects and I can make one of them appear easily enough, (I have my own working script for that) but I don't quite know how to make them all appear simultaneously.  

My preferred method would be to declare an array of the necessary data at the top and then have a loop at the part of the script that rezzes the object, that queries the array so that it can quickly and recursively rez them all, essentially (but not actually), simultaneously.  It's the "exactly how to do this" part that I'm not too sure of.  

Are llscript lists always one dimensional? (meaning I can't actually make an array)?  If they are, that means I would presumably need a list for each vector and each offset?  There are eleven objects to be rezzed and I want to make it as efficient as possible and not use fifty global variables or whatever if I don't have to.  

I have an understanding of basic scripting and of LL script but it isn't my "thing" so someone who dreams in code and wants to help would be appreciated.  

 

Thanks, 

Sylvia

 

Link to comment
Share on other sites

Yes, there is no such thing as an array in LSL.  We fake it with strided lists or, if you have a project that needs more sophisticated handling, by using JSON.  In this case, it's easy enough to just stuff a strided list in the form

list WhatWhere = ["Item One", <10,10,10>,"Item Two", <20,20,20>,"Item Three",<30,30,30>];

And then use an object_rez event to send the newly rezzed object its target location:

 

touch_start(integer num){    llRezAtRoot(llList2String(WhatWhere, count),llGetPos(),ZERO_VECTOR,ZERO_ROTATION,MyChannel);}object_rez(key id){    llRegionSayTo(id,MyChannel,llList2String(WhatWhere,count+1));
count += 2;}

You'll want to put the llRezAtRoot statement in a timer event, triggered by the touch_start event, but I'm just simplifying here.  The idea is that your touch rezzes the object and sends it a comm channel as the startup variable.  You open that channel in the newly rezzed object as it is rezzed and receive the location that is sent from the object_rez statement above.  Convert that to a vector and use llSetRegionPos to send it where you wanted it to go.  The count variable is incremented by 2 and you're ready to rez the next object.  You'll need to write the bits to run this in a timer event and stop it when you get to the end of your list.

Link to comment
Share on other sites

Thanks for the replies, 

What I have already is a script I made for a fireplace that works for rezzing single objects (in this case the burning firelog in the grate).  It seems short and efficient.  Let me know if you see anything wrong with it.  

The trouble is this new project is eleven objects and currently I have hacked it by simply having eleven scripts in the "master" object, which is at best clunky.  A second click de-rezzes the objects, so when there are eleven scripts like this the chance that they get out of sync is pretty high.  There are also a lot of pauses and pinwheeling. 

I'm really not sure where to put the loop (that would access the lists and cycle through rezzing the eleven objects) or how to code it. 

 

// ===================================// fireplacer script by Sylvia Wasp // ===================================integer     _fireOn;vector      _currentPos;vector      _fireOffset;vector      _rotPoint;vector      _newPos;rotation    _currentRot;rotation    _fireRot;default{    on_rez(integer start_param)    {        llResetScript();           }     state_entry()    {        llWhisper(59,"poke");        _fireOn = FALSE;        }    touch_start(integer total_number)    {        if (_fireOn){            llWhisper(59,"poke");            _fireOn = FALSE;            }        else{            _currentRot = llGetRot();            _currentPos = llGetPos();            _fireOffset = <0.0, 0.1, 0.0>;  //change f/pos of log from root            _rotPoint = llGetPos() + _fireOffset;            _fireRot = llEuler2Rot(<TWO_PI,PI,PI_BY_TWO>);  //the rotation            _newPos = _currentPos - ((_currentPos * _currentRot) - (_rotPoint * _currentRot));            llRezAtRoot("firelog w/fire", _newPos, ZERO_VECTOR, _fireRot * _currentRot, 42);            _fireOn = TRUE;            }                 }}
Link to comment
Share on other sites


Sylvia Wasp wrote:

Thanks, It's interesting that an array can be "faked" that way, but it seems a bit confusing to me and the list would be terribly long.  I guess three lists are the way to go for me.  

Three lists will work too, as Qie suggested. Whether you do that or use a strided list is a matter of personal style and the design of your script.  Personally, I find that I lose track of how list indices are being incremented, so I can get multiple lists out of sync and make a hash of the whole thing.  At least the elements in a strided list are all in a regular 1-2-3,1-2-3,1-2-3,1-2-3 order so I only have to keep track of one index.  If you use multiple lists, just be careful to keep them in sync and you should be fine.

Link to comment
Share on other sites

As sad as it may sound, I'm leaning against using the strided lists because of "visual confusion"  

The list of eleven object names eleven vectors and eleven rotations would wrap around the page so many times it would just look awful.  I'm more of a visual person and it's important to me to have the code clutter-free and easy to read. I find that when the code is poorly formatted or has lines that are too long to fit on my screen that it gives me a headache, lol. :smileyhappy:

Link to comment
Share on other sites

There is no reason to hardcode position/rotation offsets in a list. In fact it is bad programming because  not data driven. I would've (and did in this product) rezzed all objects from the list of their names originally in the center of the rezzer, then I would've manually positioned the objects correctly around the rezzer and recorded (via on-touch menu button) their positions/rotations relative to the rezzer. After positions/rotation are stored in the script, on subsequent rezzes the objects would be rezzed in the positions/rotations last recorded.

Of course I didn't invent a bicycle here, most commercial rezzers work this way.

Link to comment
Share on other sites


Ela Talaj wrote:

There is no reason to hardcode position/rotation offsets in a list. In fact it is bad programming because  not data driven. I would've (and did in
) rezzed all objects from the list of their names originally in the center of the rezzer, then I would've manually positioned the objects correctly around the rezzer and recorded (via on-touch menu button) their positions/rotations relative to the rezzer. After positions/rotation are stored in the script, on subsequent rezzes the objects would be rezzed in the positions/rotations last recorded.

Of course I didn't invent a bicycle here, most commercial rezzers work this way.

Well, this is kindof what I did, except I didn't do it with a commercial rezzer, I manually figured out all the offsets and rotations.  the reason for the list is also as you say, which is that I want them to rez at the same spot every time.  Basically the initial object is rezzed, you click it, and then the eleven other objects (vendors basically) rez around it in various locations.  

So, it's hard coded into a list in order that they always rez in the same spot in the same way, relative to the original object, no matter how the original object is rotated or positioned.  Each object (vendor) has a "die" script inside so a second click on the original object puts them all away.  

I realise this is an awkward way of rezzing eleven vendors but it's a peculiar and unique situation/object.  

Link to comment
Share on other sites

You don't have to have the entire list on one line. You can put the different items and their offsets on a different line like:

 

list items = [

"Item 1", pos, rot,

"Item 2", pos, rot,

etc...

];

 

You can even put comments at the end of each line. That's how I keep track of hard coded texture uuid

 

list textures =

["some uuid",//texture 1

"some uuid2",//texture 2

Link to comment
Share on other sites

Good advice, thanks.  I tend to disagree about comments though.  

I find that the popular advice to add lots of comments to scripts much more of a hinderance than a help.  It should (to my mind) be clear what's going on for the most part if the script is succinct and well laid out (again, I'm talking about vidual clutter here).  

I've rarely found a script yet where I couldn't rip out literally 90% of the coments and yet make it much clearer what's going on as a result.  But then, I only deal with simple scripts.  

Link to comment
Share on other sites

Oh yeah, of course. I only meant the comments on the list to know what's going on where it may not be clearly visible.

Something that says:

"Jfjsjjdjjsjsggh7373773hdhh",

 

Wouldn't be understandable so I'd put:

 

"Jfjsjjdjjsjsggh7373773hdhh",//bubbles

 

Not something for the end user to see, just for my own sanity when writing/updating the script

Link to comment
Share on other sites

I don't know if anyone is stil interested in this but I think I've started to work it out.  A question I have though that doesn't seem to be answered by the LSL wiki is about how to write the rotations in the strided list, and what kind of entries are allowed or not.  

In the original script for rezzing a single object, I define the rotations like so: 

llEuler2Rot(<PI,PI_BY_TWO,PI_BY_TWO>); 

because they are all 90 degree rotations and I don't have to manually figure out quaternions (as if that's gonna happen).

So a rough of my strided list for the new script I get something like: 

list vendorList =  ["leb_vendor 1", <2.625, 1.27887, -1.225>,llEuler2Rot(<PI,PI_BY_TWO,PI_BY_TWO>),                    "leb_vendor 2", <2.525, -1.265, -1.215>,llEuler2Rot(<PI,PI_BY_TWO,PI_BY_TWO>),                    "leb_vendor 3", <2.625, -1.375, -0.25>,llEuler2Rot(<PI,PI_BY_TWO,PI>,                    "leb_vendor 4", <1.78, -1.375, -0.75>,llEuler2Rot(<PI,PI_BY_TWO,PI>),                    "leb_vendor 5", <2.041, -1.375, 0.3547>,llEuler2Rot(<PI,PI_BY_TWO,PI>),                    "leb_vendor 6", <2.626, -1.375, 1.1454>,llEuler2Rot(<PI,PI_BY_TWO,PI>),                    "leb_vendor 7", <1.78, -1.375, 1.1454>,llEuler2Rot(<PI,PI_BY_TWO,PI>),                    "leb_vendor 8", <2.041, 1.40387, -0.75>,llEuler2Rot(<PI,PI_BY_TWO,PI_BY_TWO>),                    "leb_vendor 9", <2.625, 1.40387, -0.25>,llEuler2Rot(<PI,PI_BY_TWO,PI_BY_TWO>),                    "leb_vendor 10", <2.625, 1.40387, 0.75>,llEuler2Rot(<PI,PI_BY_TWO,PI>),                    "leb_vendor 11", <2.041, 1.40387, 1.1454>llEuler2Rot(<PI,PI_BY_TWO,PI_BY_TWO>)                    ];

is it actually kosher to use 11Euler2Rot like that? 

 

Link to comment
Share on other sites

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

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

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...