Table of Contents

Change Log

12 April 2013

  • Rewrote the code.

18 December 2011

  • Fixed to allow/accept names longer than 24 characters. Added feature to trap ALL. Added PRIM_TEMP_ON_REZ so that bubbles will die in all cases.

Description

Similar to cage-trappers, sometimes it might be useful to highlight an avatar by surrounding them in a bubble. Different from cage-trappers, this script is meant to simulate trapping somebody in a water bubble and to explode a few seconds after it reaches its destination. Originally, I created it for Juvon Gibbs as a commission and was meant for djing events, in order to thank people who tipped the DJ.

The name "Trapper" is misleading since these scripts do not effectively trap an avatar into the bubble since the bubble itself is phantom, allowing avatars to pass through it at any time. Moreover, the bubble bursts with a 2 second delay after it has reached the chosen avatar's position by using llDie.

The script also uses at_target and not_at_target to make the bubble homing an go after the avatar instead of just the last position the avatar was found to be.

I am posting it here since it uses an alternative way to rez an object and to pass an avatar's name to that object.

Hash a String to a Number

Usually, whenever you rez an object, you also have a script within that object and you need to pass data from the rezzer to the rezzed object. Conventionally, one would do that with some variation of llRegionSay/ llWhisper. However, that usually implies that the script in the rezzed object must listen on a channel and the rezzer might even have to use the timer event in order to make sure that the rezzed object has received the data.

For example:

llRezObject("object name", ...);
llRegionSay(channel, data);

this might not work as expected since there is a delay between rezzing the object, the object rezzed setting up a listen and the llRegionSay that the rezzer uses to pass the data. The workaround is to put llRegionSay inside a 'timer and continuously broadcast the data to make sure that the rezzed object has received it.

Here might be a (risky) alternative:

The function llRezObject, takes as last parameter a number which will be passed to the object that will be rezzed. The problem is that, frequently, you need to pass a string and the fact that llRezObject can only pass an integer does not help. In order to do that, we can try to hash the string to a number. For example, this script simply adds up the alphabetic positions of the letters in a string and uses that number to identify the string:

integer Name2Number(string name) {
    list alpha = ["*", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
    integer itra;
    integer ahash;
    for(itra=llStringLength(name), ahash=0; itra>-1; --itra) {
        ahash += llListFindList(alpha, (list)llToLower(llGetSubString(name, itra, itra)));
    }
    return ahash;
}
...
llRezObject("object name",...,Name2Number(avatar name));

When the rezzed object rezzes, it uses the same algorithm to compute the hashes of the avatar names it finds around it. When the two numbers are identical, the rezzed object has found the avatar chosen by the rezzer.

There are certain problems with that, for example:

I am unsure how frequent the problems above might appear in reality. Of course, the probability of encountering one of the problems above rises with the number of avatars to be scanned. One could strengthen the algorithm above, by using capital letters as well.

However, In case one has access to the key of the object, one might use:

integer Key2Number(key objKey) {
  return ((integer)("0x"+llGetSubString((string)objKey,-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
}
...
llRezObject("object name",...,Key2Number(some key));

Which is taken from llDialog and usually meant to generate channel numbers. However, it is still just a hash of a key, resulting in a number.

The rezzed object, will have to scan the vicinity again for object or avatars and compare the number it received (in the on_rez event) by using a hashing algorithm.

By doing that, you would have at least:

  1. freed up the timer event in the rezzer allowing you to use it for something else.
  2. got rid of llRegionSay / llWhisper.
  3. freed up the listen event in the rezzed object.

Setting up the Bubble Trapper

  1. Create a sphere primitive and drop the code and drop the Bubble Trapper - Bubble and optionally the Bubble Trapper - Animation. You can also change the the texture and transparency. Save the scripts and take the bubble primitive to your inventory.
  2. Create another primitive which will be the rezzer and drop the Bubble Trapper - Launcher script into it.
  3. Open the rezzer primitive you created at point 2 and add the bubble primitive you created at point 1 inside it.

The result will look something like this:

The red box is the launcher and it contains the launcher script and the bubble.

You are set. Just click the primitive and select the avatar to launch the bubble at.

Index