object rezzer with next and back
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-02-2008 22:55
i'm trying to make a simple display table with next and back buttons. i can't figure out what i'm doing wrong with this script. when i click the next button to the end of the list, it starts over at the beginning, but if i click back to the beginning, and then click it again, it should start over at the end of the list, but it's giving me the error "Could not find object" can anyone help me fix it? integer x = 0; default { state_entry() {
}
link_message( integer sender, integer num, string message, key id ) { if( num == 0 ) { llWhisper(5,"die"); llSleep(0.25); integer obj = llGetInventoryNumber(INVENTORY_OBJECT); llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0); x++; if (x == obj) x = 0; }
else { llWhisper(5,"die"); llSleep(0.25); integer obj = llGetInventoryNumber(INVENTORY_OBJECT); llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0); x--; if (x == 0) x = obj; } } }
edit: oops, actually this script that i posted is actually not giving me the error, it just keeps rezzing the first item in the list. i've been messin with it for a few hours and can't remember what was different that was giving me the error edit again: ok i figured out what i had changed. the last line in the "else" state was "if (x == 0) x = 0;" instead of "if (x == 0) x = obj;"
|
|
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
|
08-02-2008 23:58
Make it "if( x == 0 ) x = obj - 1;". If there are 5 items on the list, the index of the last one is 4, not 5.
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-03-2008 06:26
From: Deanna Trollop Make it "if( x == 0 ) x = obj - 1;". If there are 5 items on the list, the index of the last one is 4, not 5. i've tried that as well, doesn't work either, i'm thinking it may be in the wrong place, but i don't know where it should go
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-03-2008 07:12
ugh, silly me, i figured it out, it should be if( x < 0 ) x = obj - 1; it's in the correct place. i just thought i had tried it already, anyways, here's the full script again with comments added if anyone wants it and the scripts for each button and the "die" listener for the object itself. From: someone //Object Display Table with next and back buttons. //Written by Ruthven Willenov. //May be used freely however you want //Drop this Script into the root prim, along with the objects you would like to display. integer x = 0;//tells the script to start at the first item in the list, "0" is the first item default { link_message( integer sender, integer num, string message, key id )//listen for message from other links { if( num == 0 )//what do to if the "next" button is pressed { llWhisper(5,"die"  ; //tells the currently displayed object to go away, change the channel it whispers on for each table, so they don't kill objects on other tables llSleep(0.25);//gives it time to go away integer obj = llGetInventoryNumber(INVENTORY_OBJECT);//checks how many objects are in the list llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0);//rezzes the object 1 meter above the table x++;//tells it to rezz the next one in the list if (x == obj) x = 0;//if you were at the last one in the list, start over at the beginning } if( num == 1 )//what do to if the "back" button is pressed { llWhisper(5,"die"  ;//again, tells the current object to go away,change the channel it whispers on for each table, so they don't kill objects on other tables llSleep(0.25);//again, gives it time to go away integer obj = llGetInventoryNumber(INVENTORY_OBJECT);//again, checks how many are in the list llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0);//again, rezzes the object 1 meter abaove the table x--;//tells it to choose the previous item in the list if (x < 0) x = obj-1;//if you were at the beginning, start over at the end } } } From: someone //Object Display Table next button //Written by Ruthven Willenov. //May be used freely however you want //Drop this Script into the "next" button prim. default { touch_start(integer total_number) { llMessageLinked( LINK_ROOT, 0, "", NULL_KEY ) ; //sends a blank link message to the root with the number "0", to represent, this is the next button } }
From: someone //Object Display Table back button //Written by Ruthven Willenov. //May be used freely however you want //Drop this Script into the "back" button prim. default { touch_start(integer total_number) { llMessageLinked( LINK_ROOT, 1, "", NULL_KEY ) ; //sends a blank link message to the root with the number "1", to represent, this is the back button } }
From: someone //Die Script, drop this into any prim of each object that is displayed so that it will go away before the next/previous item is displayed. or to clear it without showing another object simply say "die" on the correct channel ie "/5die" default { state_entry() { llListen(5,"","",""  ;//change the channel to match the table the object is in } listen(integer chan, string name, key id, string msg) { if(msg=="die"  //if the message it hears is "die" { llDie();//kills the object containing this script } } }
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-03-2008 07:16
hmm, you know, i just noticed something odd, if you go from thelast object, to the first, and then click back again, it shows the next item, instead of the last item, but then clicking back again scrolls back correctly "shrug". if anyone can figure out why it does that, and fix that, lemme know, thanks 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
08-03-2008 12:53
You might want to use the integer modulus (%) operator. It makes things look a little simpler. // Increment (circularly) x = (x+1)%obj;
// Decrement (circularly); +obj is for the case where x-1 < 0 x = (x-1+obj)%obj;
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-03-2008 13:00
From: Hewee Zetkin You might want to use the integer modulus (%) operator. It makes things look a little simpler. // Increment (circularly) x = (x+1)%obj;
// Decrement (circularly); +obj is for the case where x-1 < 0 x = (x-1+obj)%obj;
???
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
08-03-2008 13:07
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-03-2008 13:21
so i would replace
if( x < 0 ) x = obj - 1;
with
if x = (x-1+obj)%obj;
and the same example for the positive change? or am i completly wrong?
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
08-03-2008 23:24
You'd replace the whole x--; if (x < 0) ... construct with that bit, yes.
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-04-2008 06:27
oh ok, i got it now, but oddly it still does that weird thing, and it's not only at the end of the list like i thought. click next rezzes item 1, click back, rezzes item 2, back again, item 1, back again, last item, and vice vera when going in the opposite direction. tried moving it to the beginning of each if statement and it gives me a run time and math error. i figured it would be better to call on the next/previous item right before it rezzes because it looks like what the previous script is doing is, rezzing the selected item, then figuring out which one is next/previous, and making that the one that's rezzed next no matter which button is pressed [QUOTE[ if( num == 0 ) { x = (x+1)%obj; llWhisper(5,"die"  ; llSleep(0.25); integer obj = llGetInventoryNumber(INVENTORY_OBJECT); llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0); [/QUOTE]
|
|
Damanios Thetan
looking in
Join date: 6 Mar 2004
Posts: 992
|
08-04-2008 06:54
From: Ruthven Willenov oh ok, i got it now, but oddly it still does that weird thing, and it's not only at the end of the list like i thought. click next rezzes item 1, click back, rezzes item 2, back again, item 1, back again, last item, and vice vera when going in the opposite direction. tried moving it to the beginning of each if statement and it gives me a run time and math error. i figured it would be better to call on the next/previous item right before it rezzes because it looks like what the previous script is doing is, rezzing the selected item, then figuring out which one is next/previous, and making that the one that's rezzed next no matter which button is pressed [QUOTE[ if( num == 0 ) { x = (x+1)%obj; llWhisper(5,"die"  ; llSleep(0.25); integer obj = llGetInventoryNumber(INVENTORY_OBJECT); llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0); [/QUOTE] Well, that's exactly the behaviour you programmed  Start: x = 0 Press next: rez(0), x = 1 Press back: rez(1), x = 0 Press back: rez(0), x = last etc. As you said yourself, your script is showing the effect of the previous button press when a new button is pressed. You need to move the next/previous effects before the rez, then act upon them. Your last change is doing that, but it helps to define 'obj' before actually using it 
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-04-2008 07:45
From: Damanios Thetan Your last change is doing that, but it helps to define 'obj' before actually using it  yeah, i looked at it again after logging out of the world, and yeah i think i just need to reverse a couple of lines....hopefully, i'll try it later when i go back in world From: someone if( num == 0 ) { integer obj = llGetInventoryNumber(INVENTORY_OBJECT); x = (x+1)%obj; llWhisper(5,"die"  ; llSleep(0.25); llRezObject(llGetInventoryName(INVENTORY_OBJECT, x), llGetPos()+<0,0,1>*llGetLocalRot(),<0,0,0>,llGetLocalRot(),0); and actually the problem was more like Press next: x = 0 Press back: x = 1 Press back: x = 0 Press back: x - last etc. it was going forward once, before moving backwards correctly, or vice versa
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
08-04-2008 10:54
Hmm. Are you certain there are NO other link messages being received. Maybe put a llOwnerSay() at the beginning of your 'link_message' handler for debugging. 'num' will ALWAYS either be zero or non-zero, so if ANY script sends ANY link message to your prim for ANY reason, your code will be incrementing or decrementing. Make sure you get as many messages as you expect.
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-04-2008 12:29
From: Hewee Zetkin Hmm. Are you certain there are NO other link messages being received. Maybe put a llOwnerSay() at the beginning of your 'link_message' handler for debugging. 'num' will ALWAYS either be zero or non-zero, so if ANY script sends ANY link message to your prim for ANY reason, your code will be incrementing or decrementing. Make sure you get as many messages as you expect. . i'm quite sure, these are the only scripts i have put into the object. and actually, i made a new script that doesn't need link messages. it was inspired by a script i found for a multi pose stand that has next/previous buttons, the script detects the name of the prim that was touched. also i was trying to add a third button so that it would simply whisper "die" to help clean up faster, but it wasn't working for some reason. otherwise, the script works great except for the problem i'm having above. once i get that figured out, it should be perfect. i'm trying to make it a simple setup, cause my friend that wants to use it, has really no scripting knowledge (she's admitted it on several occasions, so no comments saying i called her dumb  )
|
|
Ruthven Willenov
Darkness in your light
Join date: 16 Jan 2008
Posts: 965
|
08-04-2008 17:46
all right, i finally got home, went in world and tried moving the line. WORKS PERFECTLY! so here's the updated scripts, this one doesn't need scripts in the buttons. and i have provided 2 listener scripts the first was used in another rezzer tool which was written by someone else. i don't remember who it was, if you wish, speak up if you wrote it the second listener is just a plain one that listens for the message "die" you only need to use one or the other of the listeners. drop this first script into the table that has 2 buttons, one named "next", the other named "back" From: someone //Object Display Table //Written By Ruthven Willenov //To Setup //First you need to drop a seperate script inside each item you want to display that listens on the specified channel for the message "die". //Second to set up the table, make the table, and make 2 buttons, name one "next" and the other "back" (without the quotes) // link the buttons to your table and position them appropriately, drop this script into the table //setup the channel, and offset correctly below //drop in the items, and you're all set integer obj = 0;//the first item in the list is always 0 not 1 integer chan = 5;//what channel to whisper on, make sure it matches the channel in the items displayed vector offset = <0.0,0.25,0.010>;//where to rezz the object relative to the the rezzer default { touch_start(integer total_number) { string button = llGetLinkName(llDetectedLinkNumber(0));//detects the name of the button that is pressed if (button == "next"  //if the next button was pressed { integer quant = llGetInventoryNumber(INVENTORY_OBJECT);//how many objects in my inventory obj = (obj+1)%quant;//call the next object in the list llWhisper(chan,"die"  ;//tells the displayed object to go away llSleep(0.25);//gives the current object time to go away llRezObject(llGetInventoryName(INVENTORY_OBJECT, obj), llGetPos()+offset*llGetLocalRot(),<0,0,0>,llGetRot(),0);//rezz the object } else if (button == "back"  //if the back button is pressed { integer quant = llGetInventoryNumber(INVENTORY_OBJECT);//how many objects in my inventory obj = (obj-1+quant)%quant;//call the previous object in the list llWhisper(chan,"die"  ;//tells the displayed object to go away llSleep(0.25);//gives the current object time to go away llRezObject(llGetInventoryName(INVENTORY_OBJECT, obj), llGetPos()+offset*llGetLocalRot(),<0,0,0>,llGetRot(),0);//rezz the object } } } this second script is the listener that makes the object die before the next one is rezzed. it also will fix the rotation for you. and it removes itself from the object if it has changed owners. From: someone //On Rez Change Rotations & Die // Put this script in any object that needs to change its rotations when rezzed on the rezzer table. //This script will delete it self if the object it is in changes ownership. // This will allow you to sell copies of the object directly off of the rezzer display item. // This script will change the rezz rotations of the object it is in. It is often necessary if the base prim of the object does not have zero rotations. //ALSO you must edit the <0,0,0> X,Y,Z numbers to say where you want the object to rezz in relation to the center of the rezzer table. key owner; rotation rot_xyzq; default { state_entry() { owner = llGetOwner(); vector xyz_angles = <0,1.0,0>; // This is to define a 1 degRee change(use the rotation #'s you see in the edit window) vector angles_in_radians = xyz_angles*DEG_TO_RAD; // Change to Radians rot_xyzq = llEuler2Rot(angles_in_radians); // Change to a Rotation } on_rez(integer rez_num) { if(owner != llGetOwner()) llRemoveInventory(llGetScriptName()); else llSetRot(llGetRot()*rot_xyzq); //Do the Rotation... } }
this last script is the plain listener. it doesn't need to be in the root prim as it doesn't change the rotation, so if you are selling the contents of the object displayed, it's best to put this one in a child prim From: someone //Die Script, drop this into any prim of each object that is displayed so that it will go away before the next/previous item is displayed. or to clear it without showing another object simply say "die" on the correct channel ie "/5die" default { state_entry() { llListen(5,"","",""  ;//change the channel to match the table the object is going to be rezzed from } listen(integer chan, string name, key id, string msg) { if(msg=="die"  //if the message it hears is "die" { llDie();//kills the object containing this script } } }
|