Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Problem with llGetAttached() not returning correct value

Bones Outlander
Registered User
Join date: 16 Jan 2008
Posts: 30
10-06-2009 15:01
Hi everybody,

I have an object that can be rezzed in-world or worn. Depending on whether it's rezzed or worn it will resize to different sizes and enable/disable certain functions.

This has been working well for over a year until I started using the Emerald viewer a few weeks ago, now when I rezz or wear the object from inventory it sometimes detects the incorrect state with llGetAttached and does the wrong things!

If I reset the script after rezzing/attaching then it sorts itself out correctly so it seems the llGetAttached() called in the on_rez event is getting executed before the object has fully attached and giving false results sometimes with the emerald client.

I thought maybe I should use the attach() event to do the resize and the llRequestPermissions call inside the running state instead of inside the on_rez, and that would be fine when the object is attached, but how would I then handle when the object is rezzed as the attach() event won't be triggered?

So... does anybody have any suggestions on how to best handle this situation to ensure the object will resize/take controls correctly when rezzed or attached from inventory?

Note: My script is rather long, so I have extracted the bits that are relevent to this discussion below rather than confusing things with lines and lines of script.;


CODE

default
{
state_entry()
{

if (llToLower(llGetObjectDesc()) =="debug"){
DEBUGMODE = TRUE;;
}
if (llGetAttached()>0){
if (llToLower(llGetObjectDesc()) =="autoresize"){ // if (iAutoResize ==TRUE){
llSetPrimitiveParams([PRIM_SIZE,<.08, .13, .04>, PRIM_ROTATION,llEuler2Rot(<0,0,120>*DEG_TO_RAD)]);
}
iHUDAttached = TRUE;
}
else {
iHUDAttached=FALSE;
if (llToLower(llGetObjectDesc()) =="autoresize"){ // if (iAutoResize ==TRUE){
llSetPrimitiveParams([PRIM_SIZE,<.5, .5, .75>,PRIM_ROTATION,llEuler2Rot(<0,0,0>*DEG_TO_RAD)]);
}
}
//
// This section loads settings from a notecard and validates them before setting state to "running"
//

state Running;
}
}
}

state Running
{
state_entry()
{
if (DEBUGMODE == TRUE) llOwnerSay("state running _ state_entry");
integer iTimer;
if (iHUDAttached == TRUE){ //If Hud is Attached to avatar
llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);
}

llListen(iChan,"",llGetOwner(),""); // Listen on user configurable channel for voice commands
llOwnerSay("Listening on channel "+(string)iChan+" use '/" + (string)iChan +" help' for instructions and commands.");
llOwnerSay("Free Memory: " +(string)llGetFreeMemory());
llSetTimerEvent(iTimer);
}

run_time_permissions(integer perms)
{
llTakeControls(CONTROL_LBUTTON, 0, 1);
}

}
on_rez(integer iRez)
{
llSetTimerEvent(0.0);
if (DEBUGMODE == TRUE) llOwnerSay("state running _ on_rez");

if (llGetAttached()>0){
if (llToLower(llGetObjectDesc()) =="autoresize"){ // if (iAutoResize ==TRUE){
llSetPrimitiveParams([PRIM_SIZE,<.08, .13, .04>, PRIM_ROTATION,llEuler2Rot(<0,0,120>*DEG_TO_RAD)]);
}
llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS);
iHUDAttached = TRUE;
}
else {
iHUDAttached=FALSE;
if (llToLower(llGetObjectDesc()) =="autoresize"){ // if (iAutoResize == TRUE){
llSetPrimitiveParams([PRIM_SIZE,<.5, .5, .75>,PRIM_ROTATION,llEuler2Rot(<0,0,0>*DEG_TO_RAD)]);
}
}

if (iDisplayText == TRUE){
llSetText(sHeader1 + "\n" + sHeader2 + "\n" + "Loading...",vTextColor,fAlpha);
}
llOwnerSay("Loading..");
integer iLength = llGetListLength(lAvi_status);

//
// Do stuff in here before enabling timer
//

llSetTimerEvent(0.5);
}


many thanks
Bones
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
10-07-2009 04:31
That seems strange, as the object's script is running server-side. The object-loading and attaching to the avatar should occur on the simulator; the viewer is just responsible for display the results.

Your script only seems to perform the test in on_rez() and state_entry(), if you want to detect when the object is attached then you should use the attach() event, it will trigger after on_rez().
_____________________
Computer (Mac Pro):
2 x Quad Core 3.2ghz Xeon
10gb DDR2 800mhz FB-DIMMS
4 x 750gb, 32mb cache hard-drives (RAID-0/striped)
NVidia GeForce 8800GT (512mb)
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
10-07-2009 07:42
You could assume in 'on_rez' that the object will not be attached, then correct that in the 'attach' event.

Or you could start a timer from 'on_rez' and if the timer happens before 'attach', assume it won't be attached. Of course, you can actually attach an object from in-world instead of your inventory, and you'll get the 'attach' event way after the 'on_rez' event. If the object is dropped back in-world and then attached again, you may even get 'attach' events without associated 'on_rez' events. What's wrong with simply using 'attach'?
Bones Outlander
Registered User
Join date: 16 Jan 2008
Posts: 30
10-22-2009 05:46
Sorry for the late reply,

Thanks for the suggestions, I've changed the code to only do the llRequestPermissons in the Attach() event and in the on_rez treat the object as rezzed.

Interesting thing was, today I rezzed the object out of invemtory and it asked to take permissions while sitting on the ground! So even the Attach() event sometimes gets it wrong.

Oh well, it's been a one-off and the sim was very laggy so who knows :)
(And yes I was testin inside the attach() event that it was attaching and not detaching)

Bones