Jump to content

make specific avatar teleport after collision_start event


testgenord1
 Share

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

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

Recommended Posts

Hi!
I've got a script that makes an avatar jump from a jumping tower into a swimming poo.
It triggers a jumping animation through a collision_start event when stepping on the tower.
After the jump the avatar having done the jump is teleported back onto the tower.
This already works.

What I want to do is the following:
As long as the avatar is using the tower, no other avatar should be able to use it.
This is why I put the jumping avatar on a list allowing only the one avatar on the list to use the script.

Here is the problem:
When that particular avatar is teleported back onto the tower, a second avatar near the tower is also teleported onto the tower without having triggered the collision_start event,
which should not happen.

I don't understand why.
Do you maybe see where the problem is?
Thank you very much in advance!
Here is the script:

string gStrAnim; //used for the animations
string gStrGesture; //used for the animations
key av;
string region;
list jumper; // List on which the colliding avatar is put. Only 1 avatar is allowed on the list.
integer ljumper; // Length of the list. Should be one.
integer avposlist; // Index of the avatar on the list.

list gLstBtnGesture = // animation buttons for dialog
[
"back flip", "dive high", "dive low",
"flip slow", "jump", "spin"
];

list gLstGestures = // animations in the inventory triggered by the buttons
[
"back flip", "dive high", "dive low",
"flip slow", "jump", "spin"
];
 
gFnDlgGestures()
{
    llDialog(av, "What jump do you want?", gLstBtnGesture, -897); // dialog menu for triggering the animations
}
  
default
{
    state_entry()
    {
        llSetPrimitiveParams([
        PRIM_COLOR, ALL_SIDES,<1.0, 1.0, 1.0>, 1,PRIM_PHANTOM,FALSE]);
        gStrAnim=llGetInventoryName(INVENTORY_ANIMATION,0); // animations
    }
     collision_start(integer num)
   {
       llSetTimerEvent(1.0);
       av = llDetectedKey(0);
       llListen(-897,"",NULL_KEY,"");
       gStrAnim=llGetInventoryName(INVENTORY_ANIMATION,0); // animations
       ljumper = llGetListLength(jumper); // length of the list containing the avatar; should be 0 here.
       llOwnerSay("number of avs on list = " + (string)ljumper);
      
       if(ljumper < 1) // If no avatar is on the list yet ...
       {
           jumper = [av] + jumper; // avatar is put on the list.
           ljumper = llGetListLength(jumper); // length of the list containing the avatar; should be 1 now.
           llOwnerSay("putting " + (string)av + "on the list");
           llOwnerSay("number of avs on list = " + (string)ljumper);
           avposlist = llListFindList(jumper,av);
           if(avposlist != -1) // if avatar is found on the list ...
            {
                llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION); // ... request permission to animate.
                llOwnerSay("requesting permission from " + av);
            }
        }
        else
        {
            llOwnerSay("list is full"); // If 1 avatar is already on the list, no second avatar is accepted.
        }
    }      
    run_time_permissions(integer perm)
    {
        if(perm & PERMISSION_TRIGGER_ANIMATION)
        {
            gFnDlgGestures(); // dialog menu for animations is started.
        } 
    }
    listen(integer channel, string name, key id, string message)
    {
        if (llListFindList(gLstBtnGesture, [message]) != -1) // animation is started through the menu.
        {
            region = llGetRegionName();
            gStrGesture = llList2String(gLstGestures, llListFindList(gLstBtnGesture, [message]));
            llStartAnimation(gStrGesture); // animation is performed.
            llSleep(0.5); 
            llSetPrimitiveParams([
            PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 0,PRIM_PHANTOM,TRUE]);
            llSleep(1.5);
            llPlaySound(llGetInventoryName(INVENTORY_SOUND,0),1);
            llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES,<1.0, 1.0, 1.0>, 1,PRIM_PHANTOM,FALSE]);
            llSleep(5.0); 
            llSensor ("jumping point", NULL_KEY, PASSIVE ,96.0,PI); // After performing the animation, the script searches for the jumping tower.
        }
    }
    sensor(integer number)
    {
        vector det_pos = llDetectedPos(0);
        avposlist = llListFindList(jumper,av);
        if(avposlist != -1) // If the avatar is on the list ...
        llOwnerSay(av + "is on the list and teleported");
        {
            llTeleportAgent(av,"", det_pos, det_pos); // ... the avatar is teleported back onto the jumping point.
            llResetScript();
        }
    }
}

 

Link to comment
Share on other sites

I don't understand why you are creating a list at all. It will never have more than one avatar on it, so you never need to sort through it to find the one you need to deal with. You could shorten your script considerably and remove some potentially troublesome logic by just dealing with that one avatar.  Just set a flag when one avatar has triggered the collision_start event and prevent anyone else from triggering it until the full sequence has ended.

You are using llTeleportAgent, which needs to be run in an Experience. If it isn't, that function will teleport only the script's owner. 

Link to comment
Share on other sites

Thank you very much for your quick reply.
I'm using the script on Opensim. On Opensim, you can teleport non-owner avatars without experience events.

Strangely, in this case however, the owner is teleported in addition to the colliding avatar.
(Both are teleported.)
This is why I thought a list might help, but it causes the same problem.

I guess this might be more an Opensim problem then.
Thank you very much for trying to help, though!
 

Link to comment
Share on other sites

Aha.  I have no experience in Opensim, so I can't be sure how things work in that environment. However, I suspect that you can make your problem go away by just getting rid of the list.

collision_start (integer num)
{
    if (!iTouched)
    {
        iTouched = TRUE;
        kAv = llDetectedKey(0);
        llSetTimerEvent(60.0);
        // Do other stuff to handle jumping
    }
}

sensor (integer num)
{
    vector detPos = llDetectedPos(0);
    if (llGetPermissions() & PERMISSION_TELEPORT)
    {
        llTeleportAgent(kAv, "", detPos, detPos);
    }
    iTouched = FALSE;
    llSetTimerEvent(0.0);
}

timer()
{
    llSetTimerEvent(0.0);
    iTouched = FALSE;
}

Be sure to make iTouched a global integer variable and kAv a global key variable.  Also, don't forget to llRequestPermissions(kAv,PERMISSION_TELEPORT)    and to follow it up in your run_time_permissions event.   If necessary, you could use a test in the timer event instead:

if ( ( llGetAgentSize(kAv) == ZERO_VECTOR) || ( iCount > 6) )  // That is, if the avatar has left the region or you've checked more than 6 times ....
{
    llSetTimerEvent(0.0);
    iTouched = FALSE;
    iCount = 0;
}
else
{
    ++ iCount;
}

 and then llSetTimerEvent(10.0) in the collision_start event rather than using 60 seconds.  That would have the advantage of setting iTouched to FALSE sooner if the avatar leaves the region quickly.  Again, be sure to make iCount a global integer variable.

EDIT: Small afterthought .... you really ought to check llGetAgentSize(kAv) before you llTeleportAgent anyway, to avoid getting an error if the person has teleported away or logged out or crashed.

Edited by Rolig Loon
typos, of course
  • Like 1
Link to comment
Share on other sites

A nice way to do this would be to move the diver, after they're done diving, to the base of the tower. (Better, near the base of the tower, with a random offset to avoid pileups.) Then they climb back up the tower (sit on something, get moved to top of tower while doing a climbing animation.) If the sit-on to climb object only has one sit target, only one person at a time can climb the tower. This will give you some traffic control while retaining free will.

Even better, after diving, the avatar should be able to swim. There are swim HUDs. (Is there a full-perm one you could mod into an experience?) Dive, swim, climb out, climb tower, repeat. Just like RL.

  • Like 1
Link to comment
Share on other sites

Hi again!
Thank you very much for your suggestions!
Somebody on OpenSim wrote a completely new script for me, solving the problem.
I'm posting it below.
Since it is for Opensim, it does not contain the experience permission, which would have to be added for SL.
I might add your suggestions, for example the swimming animations, to the script later.
Thank you very much, once again!

// Diving Collision v0.1 by djphil (CC-BY-NC-SA 4.0)

string jumpto = "jumping point";
float timeout = 30.0;
float range = 32.0;

list animations = [
    "backflip", 
    "jump",
    "sit"
];

string animation;
string region;
key user_uuid;
integer canal;
integer echo;

default
{
    state_entry()
    {
        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0,
            PRIM_PHANTOM, FALSE
        ]);

        region = llGetRegionName();
        integer number = llGetInventoryNumber(INVENTORY_ANIMATION);
        if (number <= 0) {llOwnerSay("Animation(s) missing ..."); return;}
        integer length;
        integer i;

        do {
            animation = llGetInventoryName(INVENTORY_ANIMATION, i);
            length = llStringLength(animation);
            if (length > 0 && length < 24) animations += llGetInventoryName(INVENTORY_ANIMATION, i);
            else llOwnerSay("Invalid animation name " + animation);
        }
        while (++i < number);

        length = llGetListLength(animations);
        if (llGetListLength(animations) < 13) state ready;
        else llOwnerSay("Invalid animation number ...");
    }
}

state ready
{
    collision_start(integer n)
    {
        user_uuid = llDetectedKey(0);
        state diving;
    }
}

state diving
{
    state_entry()
    {
        canal = -1 -(integer)("0x" + llGetSubString( (string)user_uuid, -7, -1));
        echo = llListen(canal, "", user_uuid, "");
        llDialog(user_uuid, "What jump do you want?", animations, canal);
        llSetTimerEvent(timeout);
    }

    listen(integer channel, string name, key id, string message)
    {
        llSetTimerEvent(0.0);
        llListenRemove(echo);
        animation = message;
        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_COLOR, ALL_SIDES, ZERO_VECTOR, 0.0,
            PRIM_PHANTOM, TRUE
        ]);
        osAvatarPlayAnimation(user_uuid, animation);
        llSleep(1.0);
        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 1.0,
            PRIM_PHANTOM, FALSE
        ]);
        //llSleep(1.0);
        llPlaySound(llGetInventoryName(INVENTORY_SOUND, 0), 1.0);
        llSensor(jumpto, NULL_KEY, PASSIVE, range, PI);
    }

    sensor(integer n)
    {
        integer i;

        for (i = 0; i < n; i++)
        {
            vector det_pos = llDetectedPos(i);
            rotation det_rot = llDetectedRot(i);
            vector lookat = llRot2Euler(det_rot) * RAD_TO_DEG;
            //llSleep(5.0);
            osTeleportAgent(user_uuid, region, det_pos, lookat);
            osAvatarStopAnimation(user_uuid, animation);
            user_uuid = NULL_KEY;
            state ready;
        }
    }

    no_sensor()
    {
        llSetTimerEvent(0.0);
        llListenRemove(echo);
        osAvatarStopAnimation(user_uuid, animation);
        llOwnerSay(jumpto + " no found ...");
        state ready;
    }

    collision_start(integer n)
    {
        integer i;

        for (i = 0; i < n; i++)
        {
            key uuid = llDetectedKey(i);

            if (uuid != user_uuid)
            {
                llSay(PUBLIC_CHANNEL, "Sorry " + llKey2Name(uuid) + ", the diving board is currently used by " + llKey2Name(user_uuid));
            }
        }
    }

    timer()
    {
        llSetTimerEvent(0.0);
        llListenRemove(echo);
        state ready;
    }
}



 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1575 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...