Jump to content
Sunbleached

unpacker script works not proper

Recommended Posts

Hello! I have this script unpacker hud with social buttons and reverse side option, detach etc, but it does not work quite correctly. The first time it unpacks normally, but the second time I wear it and try to unpack I have to click twice. Does anyone know the reason and how to eliminate it?



// Links must begin with http:// or https://
string link1 = "https://marketplace.secondlife.com/stores/111111";
string link1_name = "Marketplace";

string link2 = "http://www.facebook.com";
string link2_name = "Facebook";

string link3 = "http://www.instagram.com";
string link3_name = "Instagram";

string link4 = "http://www.twitter.com";
string link4_name = "Twitter";

string link5 = "http://www.youtube.com";
string link5_name = "Youtube";

// Needed for basic functionality.
float alpha = 0.5;
integer ocillator;

default
{
    on_rez(integer n)
    {
        if(!llGetAttached())
        {   // If the object is rezzed on the ground, try attaching to owner's HUD.
            llOwnerSay("Please allow me to be on your HUD!");
            llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
        }
    }

    run_time_permissions(integer permissions)
    {
        if(permissions & PERMISSION_ATTACH)
        {   // If permission was granted, attach to owner's HUD.
            llAttachToAvatar(ATTACH_HUD_CENTER_1);
        }
    }

    attach(key id)
    {
        if(id)
        {
            llSetRot(llEuler2Rot(<0,270,270> * DEG_TO_RAD));
        }
    }

    touch_start(integer num)
    {
        // Don't let others touch this HUD.
        if(llDetectedKey(0) != llGetOwner()) return;

        integer face = llDetectedTouchFace(0);

        if(face == 1) // When the first (front) face is touched...
        {
            // Get the names of all inventory items.
            num = llGetInventoryNumber(INVENTORY_ALL);
            list items; while (num--)
            {
                if(llGetInventoryName(INVENTORY_ALL, num) != llGetScriptName())
                    items += llGetInventoryName(INVENTORY_ALL, num);
            }

            // Send the items as a folder with the same name as this object.
            llGiveInventoryList(llGetOwner(), llGetObjectName(), items);
            // Turn around to show social media buttons.
            llSetRot(llEuler2Rot(<0,90,90> * DEG_TO_RAD));
        }
        else if(face == 2)
        {
            if(llGetAttached())
            {
                llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
                llDetachFromAvatar();
            }
        }
        // When the social media buttons are touched...
        else if(face == 7)
        {
            llOwnerSay("Follow me on ["+link1+" "+link1_name+"]!");
        }
        else if(face == 6)
        {
            llOwnerSay("Follow me on ["+link2+" "+link2_name+"]!");
        }
        else if(face == 5)
        {
            llOwnerSay("Follow me on ["+link3+" "+link3_name+"]!");
        }
        else if(face == 4)
        {
            llOwnerSay("Follow me on ["+link4+" "+link4_name+"]!");
        }
        else if(face == 3)
        {
            llOwnerSay("Follow me on ["+link5+" "+link5_name+"]!");
        }
    }

    state_entry()
    {
        llSetRot(llEuler2Rot(<0,270,270> * DEG_TO_RAD));
        llSetTimerEvent(0.1);
    }

    timer()
    {
        // If the alpha has reached a limit,
        //  change which way the alpha changes.
        if(alpha < 0.1 || alpha > 0.9)
            ocillator = !ocillator;

        // Increase or decrease the alpha
        if(ocillator)   alpha += 0.05;
        else            alpha -= 0.05;

        llSetAlpha(alpha, 0);
    }

    changed(integer change)
    {
        if(change & CHANGED_OWNER) llResetScript();
    }
}

 

Share this post


Link to post
Share on other sites
13 minutes ago, Wulfie Reanimator said:

Well this looks familiar. Where'd you get it? 🙂

Hi! Its me again! You made this script custom for me.

Share this post


Link to post
Share on other sites
14 minutes ago, Sunbleached said:

Hi! Its me again! You made this script custom for me.

I don't have any chat logs from you, unless you are @ainst Composer who I wrote this for.

Either way, can you explain in detail what you expect to happen with the HUD, and what actually happens?

Looking at the script (and as I remember it), it should unpack right away if you click the right spot.

  • Like 1

Share this post


Link to post
Share on other sites
52 minutes ago, Wulfie Reanimator said:

I don't have any chat logs from you, unless you are @ainst Composer who I wrote this for.

Either way, can you explain in detail what you expect to happen with the HUD, and what actually happens?

Looking at the script (and as I remember it), it should unpack right away if you click the right spot.

Yes its me.

Ok. So the first time it unpacks normal. I accept folder, click social if needed. Then I click face 2 to close, it detaches itself. But for the next time I wear it and click face 1 to unpack it does nothing and I have to click once more, to make it give me an item... 

And all the same way unless I reset the script. And again it unpacks well for the first time, next time I wear it I need to double click it.

What am I doing wrong?

Share this post


Link to post
Share on other sites
2 hours ago, Sunbleached said:

if(llDetectedKey(0) != llGetOwner()) return;

Just guessing here that after the OP clicks and detaches from a successful event, the next time it is attached there is no prior call to llGetOwner, so the touch event is the first time the owner is queried unless a change has been triggered. This is the only point in the touch event where I can see the code would not actually do anything, so maybe adding an llGetOwner to assign the key to a global and testing against this in the event would cure the problem?

 

The only other path through the touch event where nothing happens is if the face touched is 0, but I can't see the face numbers being affected by a script reset, whereas the owner certainly would be.

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites
Posted (edited)

(Forgot to respond until I heard a beep from this tab.)

2 hours ago, Profaitchikenz Haiku said:

Just guessing here that after the OP clicks and detaches from a successful event, the next time it is attached there is no prior call to llGetOwner, so the touch event is the first time the owner is queried unless a change has been triggered. This is the only point in the touch event where I can see the code would not actually do anything, so maybe adding an llGetOwner to assign the key to a global and testing against this in the event would cure the problem?

 

The only other path through the touch event where nothing happens is if the face touched is 0, but I can't see the face numbers being affected by a script reset, whereas the owner certainly would be.

You don't need to store anything from llGetOwner, the value returned by that function can be used directly in the if-check. (I write that line a lot.) The reset is there only because the value returned by llGetOwner won't change when the owner changes, unless the script is reset.

Edit: Turns out the above is just wrong.

That said, @Sunbleached, have you tried just waiting a moment after the first click? The llGiveInventoryList function has a forced 3-second delay, so maybe it appears as if you need to click it twice, when really you just need to wait for the delay to pass?

Edited by Wulfie Reanimator
  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, Wulfie Reanimator said:

The reset is there only because the value returned by llGetOwner won't change when the owner changes, unless the script is reset. 

To be clear, when ever you call llGetOwner() it will return the current owner of the object where the script resides, you do not need to reset your script. If you have the Owner Id stored in a variable, listens set to the owner, etc., you will need to reset these on ownership change (detected in the change event). In the above script I do not see any reason why the script needs to be reset on ownership change.

I do see how this confusion can arise from the initial parts of the Wiki, as the wording is a bit ambiguous. Buit if you go the last example in the Notes, you'll see that the problem is not with the funtion llGetOwner, rather elsewhere.

  • Like 1

Share this post


Link to post
Share on other sites

2 things:

Checking for the owner of a hud in a touch event makes no sense - nobody else can touch here - but of course it will work if the hud is rezzed on ground. Thats what it's meant for I assume and it shouldn't have any influence here.

What happens if you click the detach/close button?

            if(llGetAttached())
            {
                llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
                llDetachFromAvatar();
            }

It will put an entry into the event queue for a run_time_permission event
then it will detach

Now the event queue will be processed and the run_time_event will try to attach the hud - but we detached so there is not enough time end that process

On next attach we have this unfinished attach to be worked at and I can imagine that this will confuse the expected order of events. Not sure about this, this is something that needs to be tested. So make a test and remove the llRequestPermissions line which is obsolete here anyways.

  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)
23 minutes ago, Wandering Soulstar said:

I do see how this confusion can arise from the initial parts of the Wiki, as the wording is a bit ambiguous. Buit if you go the last example in the Notes, you'll see that the problem is not with the funtion llGetOwner, rather elsewhere.

Huh. The misconceptions we live with. 😄 Thanks, I read the other half of the wiki and did a little test and you're absolutely correct.

23 minutes ago, Nova Convair said:

Checking for the owner of a hud in a touch event makes no sense - nobody else can touch here - but of course it will work if the hud is rezzed on ground. Thats what it's meant for I assume and it shouldn't have any influence here.

I like covering all corner-cases I can think of. If the user rezzes the HUD, I don't want it to start unpacking because someone else clicked on it -- even if that is very unlikely. (Expect the unexpected, always.)

To explain the bit of code you showed, it's very deliberate.

  1. "If this HUD is attached"
  2. Request permission to attach (required for detaching)
    1. PERMISSION_ATTACH is auto-granted for attached objects
    2. Because this HUD is attached, we're guaranteed to have the permission and don't need to wait for the run_time_permissions event
  3. Detach this HUD
     
  4. The HUD is attached from inventory again
  5. run_time_permissions event begins to process
  6. "if PERMISSION_ATTACH was granted" (true)
    1. Attach this HUD to Center
      1. An attachment cannot be attached again, the function fails silently

I've tested this in-world.

Edited by Wulfie Reanimator
  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)

@Wulfie Reanimator

@Profaitchikenz Haiku

@Wandering Soulstar

@Nova Convair

Wow! Thank you all so much for your answers!

This is absolutely incredible and very interesting. I learned a lot new of scripts. And perhaps answer is obvious, and I risk to be taken as inattentive noob, but guys, still... what should I do?

 

Edited by Sunbleached

Share this post


Link to post
Share on other sites
31 minutes ago, Sunbleached said:

@Wulfie Reanimator

@Profaitchikenz Haiku

@Wandering Soulstar

@Nova Convair

Wow! Thank you all so much for your answers!

This is absolutely incredible and very interesting. I learned a lot new of scripts. And perhaps answer is obvious, and I risk to be taken as inattentive noob, but guys, still... what should I do?

 

Send your HUD to me full-perm, I guess. I'll look at it tomorrow.

As it stands, there doesn't seem to be anything wrong with the script you've posted here. Also:

6 hours ago, Wulfie Reanimator said:

That said, @Sunbleached, have you tried just waiting a moment after the first click?

 

  • Thanks 1

Share this post


Link to post
Share on other sites

how about doing the llGetInventoryList in the attached event, as well as getting permission to attach. In the touch event, check that it's attached to a hud

integer attached = llGetAttached();
if(attached > 30 && attached < 39)//if in the range of 31-38, it's a hud

if it's not, return. only the owner can touch their hud, so no  need to see if the owner is the one touching.

i modified it a bit to only work when attached, create the list on attach, and to account for no-copy items.

In the runtime_permissions, i changed it to check if it's already attached before attempting to attach.

on attach i also added again the attach perms so it would be able to detach.

changed the touch command for detach to only check if it has perms then detach.

Not tested for other buttons, but i didn't mess with anything else anyways

// Links must begin with http:// or https://
string link1 = "https://marketplace.secondlife.com/stores/111111";
string link1_name = "Marketplace";

string link2 = "http://www.facebook.com";
string link2_name = "Facebook";

string link3 = "http://www.instagram.com";
string link3_name = "Instagram";

string link4 = "http://www.twitter.com";
string link4_name = "Twitter";

string link5 = "http://www.youtube.com";
string link5_name = "Youtube";

// Needed for basic functionality.
float alpha = 0.5;

key owner;
integer ocillator;
list inventory = [];
list nocopy;
getitems()
{
    integer num = llGetInventoryNumber(INVENTORY_ALL);
    inventory = [];
    string script = llGetScriptName();
    while (num--)
    {
        string name = llGetInventoryName(INVENTORY_ALL, num);
        if(name != script)
        {
            integer perms = llGetInventoryPermMask(name,MASK_OWNER);
            if(perms & PERM_COPY)
            {
                inventory += name;
            }
            else
            {
                nocopy += name;
            }
        }
    }
}
default
{
    on_rez(integer n)
    {
        if(!llGetAttached())
        {   // If the object is rezzed on the ground, try attaching to owner's HUD.
            llOwnerSay("Please allow me to be on your HUD!");
            llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
        }
    }

    run_time_permissions(integer permissions)
    {
        if(permissions & PERMISSION_ATTACH)
        {   // If permission was granted, attach to owner's HUD.
            if(!llGetAttached())//only try to attach if it's not already
            llAttachToAvatar(ATTACH_HUD_CENTER_1);
        }
    }

    attach(key id)
    {
        if(id)
        {
            llSetRot(llEuler2Rot(<0,270,270> * DEG_TO_RAD));
            llRequestPermissions(llGetOwner(), PERMISSION_ATTACH);
            owner = id;
        }
    }

    touch_start(integer num)
    {
        integer attached = llGetAttached();
        if(attached > 30 && attached < 39)//if in the range of 31-38, it's a hud
        {

            integer face = llDetectedTouchFace(0);
            if(face == 1) // When the first (front) face is touched...
            {
                integer len = llGetListLength(inventory);
                if(len)
                {
                   llGiveInventoryList(owner, llGetObjectName(), inventory);
                }
                len = llGetListLength(nocopy);
                if(len)
                {
                    llOwnerSay("There are no copy items that could not be given in the folder");
                    integer i;
                    for(i = 0; i < len; i++)
                    {
                        string name = llList2String(nocopy,i);
                        llGiveInventory(owner,name);
                    }
                }
                // Turn around to show social media buttons.
                llSetRot(llEuler2Rot(<0,90,90> * DEG_TO_RAD));
            }
            else if(face == 2)
            {
                if(llGetPermissions() & PERMISSION_ATTACH)
                llDetachFromAvatar();
            }
            // When the social media buttons are touched...
            else if(face == 7)
            {
                llOwnerSay("Follow me on ["+link1+" "+link1_name+"]!");
            }
            else if(face == 6)
            {
                llOwnerSay("Follow me on ["+link2+" "+link2_name+"]!");
            }
            else if(face == 5)
            {
                llOwnerSay("Follow me on ["+link3+" "+link3_name+"]!");
            }
            else if(face == 4)
            {
                llOwnerSay("Follow me on ["+link4+" "+link4_name+"]!");
            }
            else if(face == 3)
            {
                llOwnerSay("Follow me on ["+link5+" "+link5_name+"]!");
            }
        }
    }

    state_entry()
    {
        llSetRot(llEuler2Rot(<0,270,270> * DEG_TO_RAD));
        llSetTimerEvent(0.1);
    }

    timer()
    {
        // If the alpha has reached a limit,
        //  change which way the alpha changes.
        if(alpha < 0.1 || alpha > 0.9)
            ocillator = !ocillator;

        // Increase or decrease the alpha
        if(ocillator)   alpha += 0.05;
        else            alpha -= 0.05;

        llSetAlpha(alpha, 0);
    }
}

 

  • Thanks 1

Share this post


Link to post
Share on other sites
Posted (edited)

I've taken a look at the HUD that was given to me (exact same script as in the OP), and I'm just very confused.

So after the HUD has been clicked (received folder, HUD flips around to reveal the close button) and detached, the HUD will sometimes require two clicks instead of one to react and unpack.

After only adding a couple llOwnerSay debug messages (one to each event), it happens very rarely, maybe once every 10 times. (Without the debug messages, it happens at the rate of about 30-50%.)

When it happens with the debug messages, the touch_start event just never triggers the first time the HUD is attached again after detaching. This doesn't happen during the forced delay from llGiveInventoryList because I wait for the HUD to turn around (after the delay) before detaching it.

Edit: I looked at the "Scripts Run %" of the sim I'm in (mainland) and I think this might explain it. It's hovering around 39-51% scripts run. I'm unsure why adding llOwnerSay would make such a big difference, though.

Edit 2: I spoke to OP, and the problems occur even in a sim with 100% scripts run.

Edited by Wulfie Reanimator
  • Thanks 1

Share this post


Link to post
Share on other sites
Posted (edited)

try it without setting the alpha and see what happens

there was a recent issue with a fix change to how touches worked, which messed up touches on full alpha'd objects - which needed a rollback - and then a new fix for the fix was made. It might be that your script is now identifying a new issue as a consequence of this latest fix  

Edited by Mollymews
  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)
4 minutes ago, Mollymews said:

try it without setting the alpha and see what happens

there was a recent issue with a fix change to how touches worked, which messed up touches on full alpha'd objects - which needed a rollback - and then a new fix for the fix was made. It might be that your script is now identifying a new issue as a consequence of this latest fix  

Do you have a link to the JIRA for that, out of curiosity? But I just tested having no transparency and no luck -- first touch after re-attaching is still ignored very often.

Edited by Wulfie Reanimator
  • Thanks 1

Share this post


Link to post
Share on other sites
4 minutes ago, Mollymews said:

try it without setting the alpha and see what happens

there was a recent issue with a fix change to how touches worked, which messed up touches on full alpha'd objects - which needed a rollback - and then a new fix for the fix was made. It might be that your script is now identifying a new issue as a consequence of this latest fix  

I just removed timer event with alpha and set hud alpha to 0 and still no changes.

Share this post


Link to post
Share on other sites

There are no state changes in this script so this note from the wiki should not apply:
"Changing state from within touch_start can cause the next occurrence of THIS touch_start code to be missed."

However, maybe the llDetachFromAvatar() has the same effect as a state change. If that is the case the problem can be solved by using touch_end() instead of touch_start(). Worth to try. 
 

  • Like 2
  • Thanks 2

Share this post


Link to post
Share on other sites
Posted (edited)
3 hours ago, Wulfie Reanimator said:

After only adding a couple llOwnerSay debug messages (one to each event), it happens very rarely, maybe once every 10 times. (Without the debug messages, it happens at the rate of about 30-50%.)

It sounds like something in the attach/changed or touch event takes a variable amount of time to get queued/recognised or acted on. Instead of the llOwnerSay, try putting llSleep(0.1) calls in and see if it is still more reliable?

 

I have seen something similar in changed events or run_time_permissions where I had to put in short delays in order to get the desired sequence of sit-request permissions - stop sit and play new anim to work reliably.

Edited by Profaitchikenz Haiku
  • Like 1

Share this post


Link to post
Share on other sites
Posted (edited)
2 hours ago, Ron Khondji said:

There are no state changes in this script so this note from the wiki should not apply:
"Changing state from within touch_start can cause the next occurrence of THIS touch_start code to be missed."

However, maybe the llDetachFromAvatar() has the same effect as a state change. If that is the case the problem can be solved by using touch_end() instead of touch_start(). Worth to try. 
 

Thank you very much! It works now!

@Wulfie Reanimator@Profaitchikenz Haiku@Wandering Soulstar@Nova Convair@Ruthven Willenov@Mollymews @Ron Khondji

Thank you all very much for your titanic efforts! Finally it works proper!

Edited by Sunbleached

Share this post


Link to post
Share on other sites
21 minutes ago, Wulfie Reanimator said:

@Sunbleached That's good to hear, but what was the change that fixed the issue?

I used touch_end() instead of touch_start() and it somehow solved problem, but I dont really understand what happened, but it works!

  • Thanks 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...