Jump to content

ellestones

Resident
  • Posts

    716
  • Joined

  • Last visited

Posts posted by ellestones

  1. the simpliest way to do your own multi-sit is to put a script in each seat prim of the linkset. Each seat prim having a SitTarget yes

    when a avatar sits on the linkset. Change event fires.  In the change event  then yes, use llAvatarOnSitTarget() as the agent key for request permissions

    • Thanks 1
  2. about why shops and businesses still shut on Sundays in some countries

    yes in the beginning it was for religious reasons in the main. But also for family reasons which become more of a reason as the industrial revolution progressed.  Then in response to workers organising themselves at that time, the 40 hour work week was realised. So the weekend in most western countries  became family time at least for most workers, other than emergency and critical services workers

    in the last 30-40 years in lots of western countries the idea that we work Monday to Friday and have the weekend off to spend with our families has been eroded

    • Like 4
  3. to answer your specific question about how to stop the animation

    when the avatar stands then the linkset changes, so we know that they have got off. The script still has their animation permission, so we can apply the llStopAnimation to them even tho they are no longer sitting

    .

  4. a script can only contain 1 set of agent (avatar) permissions at a time

    when an avatar sits the script obtains their permissions

    when a 2nd avatar sits then the script obtains this 2nd avatar's permissions, which removes the 1st avatar's permissions from the script

    a multiple avatar seat requires 1 script for each sitter, when we want to do anything further (after the initial sit) to the avatars that require their permission

    is why Cindy in the other post referred you to the AVSitter script system. Mutlti-sits are a standard feature of AVSitter. And AVSitter is the most widely used sit system in SL

    this said. You can make your own. But you will need at least a sitter script for each seat

     

     

    • Thanks 1
  5. 22 minutes ago, Skell Dagger said:

    There is a vast difference between 'being alone' and 'being lonely'.

    agree

    is pretty much where the OP got off to a not very good start. As Scylla says in the OP also, this is all clickbaity

    had it been worded to say that Scylla's observations and conversations with some of her male friends indicate that hetero men when logged in to SL prefer the company of women then the conversation would have been all over on the first page. Bu it wasn't so

    fwiw in SL I have 10 men and 8 women friends. When my men friends are not romancing their partners then they hang out together.  Talking about stuff, politics, women, the weather. Compare their planes, cars, sailboats, building stuff, etc etc.  All the same things men do in the real world when they get together

     

    • Like 1
  6. 12 minutes ago, Prokofy Neva said:

    Try that move and then have your SL lock up, freeze, crash, or simply take too long to do anything. 

    See if you "cut" is still there when you re-log.

    Go ahead, I'll wait.

    this is a really good point

    i have hardly any no-copy/transfer-only items. You do. That's the difference

    i also think quite a few others on here don't get what are you saying because like me they have very few no-copy items that they have paid for

  7. for completeness, add other example code snippet for use cases where more than 1 value can be in a level, breaking when there are no values in a level

    integer binary;
    do
    {
        binary = bcopy & mask;
        if (binary)
        {
            // binary can be: [00001...11111]
            // add a levels divider
            values += " |";
            integer i;
            for (i = 0; i < SPAN; i++) 
            {   // (1 << i) is a 1 bitmask created by leftshifting as we loop
                //  the bitmask set is: 00001 00010 00100 01000 10000  
                value = levelcounter * SPAN + bit_bin2num_MOD(binary & (1 << i));
                values += " " + (string)value;
            }                
            levelcounter++;
            bcopy = bcopy >> SPAN; // delete the values from bcopy              
        }
    } while (binary);

     

  8. and the 2nd script which builds off the primer above

    is an example that explores a solution similar-ish to what Claydoo mentioned

    to make it easer to follow the code we go with [5-9,10-14,15-19,20-24]. And for this example case we make some conditions:

    - these 4 ranges are 4 levels in a game
    - the player must score at least 1 value at each level to complete the game
    - the player can play a level as many times as they like but only their last score at a level will be recorded and counted
    - the player can progress to the next level when they have scored, as and when they choose
    - the game is over when the player scores on every level

    the purpose of this example code is to find out if the player has completed the game or not. And what have they scored on each level

    integer bitarray = 0;
    integer BASE = 5;   
    integer LEVELS = 4;  // number of game scoring levels. No score is level 0
    integer SPAN = 5;    // span of each level. number of score elements in the level
    
    integer bit_status(integer value)
    {  // is the value stored or not? Return TRUE when yes. FALSE when no
        return (bitarray & (1 << (value - BASE))) > 0;
    }
    
    bit_add(integer value)
    {   // add the value to the array. When the value is already in the array do nothing
        if (!bit_status(value))
            bitarray = bitarray | (1 << (value - BASE));
    }
    
    integer bit_bin2num_MOD(integer binary)
    {   // return the decimal value of the binary parameter 
        // binary inputs: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, ...
        // when the binary bit is 1 returns value else returns 0
        return (integer)(llLog(binary) / llLog(2)) + BASE;
    }
    
    default
    {
        state_entry()
        {
            // pick some random numbers to populate the array
            // placing 1 value in each level. To simulate that the player has completed the game
            // from the set: 0|1|2|3 * 5 + 0|1|2|3|4 + 5 
            integer value;
            integer i;
            for (i = 0; i < LEVELS; i++)
            {                       
                value = i * SPAN + (integer)llFrand((float)SPAN) + BASE;  
                bit_add(value); 
            }
    
            // now we loop thru the array to get the values
            // we could loop thru every array element (20 steps) and check bit_status to get the value
            // but because of the way the game levels are structured then we can do it in 5 or less steps
            // 5 steps when the player has completed the game. 1 to 4 steps when they havent 
        
            integer bcopy = bitarray;  // make a copy of the array
            
            // lets for this purpose assume that we want to safeguard against any bits above 20 that may have 
            // somehow got set spuriously by some bug elsewhere in our game code
            // we could just stick the needed absolute value into the mask but lets make it dynamically  
            // our game uses 20 bits so we make a mask 20 bits wide. 4 levels * span of 5 = 20
            // because LSL integers are signed the 31th bit is the sign bit so we clear that bit if is spuriously set
            bcopy = llAbs(bcopy);
            integer mask = 0x7FFFFFFF >> (31 - (LEVELS * SPAN)); // 20 bit mask == 0xFFFFF
            // then we AND our bcopy with the mask to clear out any spurious bits that might be in the unused part
            bcopy = bcopy & mask;
    
            // now we need a mask for the span. Same principle. Span is 5 bits wide
            mask = 0x7FFFFFFF >> (31 - SPAN);  // 5 bit mask == 0x1F
        
            // then we want a counter numerating the level the player is on
            integer levelcounter;
            // and a string to store the values in
            string values = ". Values:";
      
            // lets loop by level, breaking when a level has no value
            // in this simulation all levels have a value 
            // test for breaking by adding values to only some of the lower levels
            integer binary;
            do
            {
                binary = bcopy & mask;
                if (binary)
                {
                    value = levelcounter * SPAN + bit_bin2num_MOD(binary);
                    values += " " + (string)value;
                    levelcounter++;
                    bcopy = bcopy >> SPAN; // delete the value from bcopy              
                }
            } while (binary);
    
            llOwnerSay((string)"Level reached: " + (string)levelcounter + values);
       }
    }

     

    • Thanks 1
  9. ok

    i had to actually write some scripts inworld to make sure I got the syntax right, instead of doing off the top off my head like I usually do. But anyways :)

    i made 2 example scripts. I post the 1st here which is a kinda primer on bit arrays.  I will post the 2nd separately as it builds on the primer and explores  an aspect of Clydoo's original post

    when have scripts to look at then can discuss things more easy. How does that work, how else could it be done, etc

    integer bitarray = 0;   // our array of bits where we store upto 31 values
                            // 31 and not 32 as LSL uses signed integers and things can get murky when we use the sign bit for storage
    integer BASE = 5;       // BASE is typically 1. But we set to 5 as OP mentioned a base (lowest) number being 5
                            // which can help us visualise a bit array as an array of whole numbers rather than as binary bits
    // example of converting whole numbers to bit positions: 
    // BASE = 5. value = 5; value - BASE = bit0. value = 6; value - BASE = bit1 
    // BASE = 20. value = 21; value - BASE = bit1. value = 42. value - BASE = bit22 
    // the functions are predicated on this method
    
    integer MAX = 25;      // highest value in the array. [BASE..MAX] == [5..25];       
    
    integer bit_status(integer value)
    {  // is the value stored or not? Return TRUE when yes. FALSE when no
        return (bitarray & (1 << (value - BASE))) > 0;
    }
    
    bit_add(integer value)
    { // add the value to the array. When the value is already in the array do nothing
        if (!bit_status(value))
            bitarray = bitarray | (1 << (value - BASE));
    }
    
    bit_remove(integer value)
    {  // remove the value from the array. When the value is not in the array do nothing
        if (bit_status(value))
            bitarray = bitarray & ~(1 << (value - BASE));
    }
    
    bit_toggle(integer value)
    {  // toggle the bit from value to 0. 0 to value. Like a lightswitch
        bitarray = bitarray ^ (1 << (value - BASE)); 
    }
    
    integer bit_bin2num(integer binary)
    {  // return the decimal value of the binary value in the bitarray 
       // binary inputs: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, ...
       // when the bitarray bit is 1 returns value else returns 0
        return (integer)(llLog(bitarray & binary) / llLog(2)) + BASE;
    }
    
    
    default
    {
       state_entry()
       {
            // we add and remove values to the array like so
            
            integer value = 6; bit_add(value);
            value = 8; bit_add(value);
            value = 6; bit_remove(value);
            value = 17; bit_add(value);
            value = 23; bit_add(value);
    
            // toggle the value 
            value = 10; bit_add(value);  // 10 is on
            bit_toggle(value); // 10 is off
            bit_toggle(value); // 10 is on
    
            // check for the value
            value = 17; integer found = bit_status(value);
            
            // using bin2num
            integer binary = 32;  // 32 is the binary value of bit5 in array when bit5 is set to 1
            // when the bit is set then value == 10 else is == 0;
            value = bit_bin2num(binary);
            llOwnerSay("bin2num " + (string)binary + " " + (string)value);
    
            // looping thru to get the values in the array
            string values = "Values: ";
            for (value = BASE; value <= MAX; value++)
            {
                if (bit_status(value)) 
                    values += " " + (string)value;
            }
            llOwnerSay(values);
        }
    }

     

     

    • Thanks 1
  10. when the values are only ever in the range [5..25] then can store them in a integer bit array

    when so then the loop to find the wanted set is reduced from 21 steps using a list to 4 steps, with 1 check only on each of the 4 steps

    if you want to explore how a bit array can work in this use case then just say ok. If so then we can get into a chat about bit arrays and how they can be used

     

    • Like 2
  11. 10 hours ago, Abadoxx said:

    Anyone care to write a sample script I can add to? I named each sound the name of the word to hopefully make things a bit easier. I will pay for it and give you a copy of the translator when it's done or send you updates as I go.

    I'm currently using this simple script where each word has to be entered separately. It's better than nothing but not very efficient. Even figuring this simple thing out took like 30mins+. Coding has never been my strong point lol.

    if you are new to LSL scripting and it took you about 30 minutes to work out what you did script, then you are way near the top of the class. 30 minutes to figure out by yourself what you have is pretty good! so don't give up ok :)

    normally when a person requests paid help then is suggested that they put the request in the Wanted forum on here. However, sometimes the request is interesting as a scripting topic. So:

    when the sound files are in Contents and are named for the word, and when a grammar-free reciter is acceptable (grammar-free meaning is up to the user to know the vocabulary) then building off what I mention yesterday. A Contents-based reciter.  This script is logically the same as Wulfie's above. We are only changing the source of the lookup method. It goes something like:  

    default
    {
       state_entry()
       {
          llListen(0, llGetOwner(), "", "");  // listen for everything typed by the owner on the open chat channel 
       }
    
       listen(integer channel, string name, key id, string msg)
       {
          msg = llToLower(msg);  // assume all sound/audio filenames are lower case
          list words = llParseString2List(msg, [" ",".","!","?"], []);
          integer numberofwords = llGetListLength(words);
          integer wordsindex;
          for (wordsindex = 0; wordsindex < numberofwords; wordsindex++)
          {
             string thisword = llList2String(words, wordsindex);
       	     if (llGetInventoryType(thisword) == INVENTORY_SOUND)
             { // this word is in Contents
                llPlaySound(thisword, 1.0);
                llSleep(1.0);  // sleep the script for ? seconds to create a space between the recited words
             }
          }
       }
    }  

    an advantage of a Contents-based grammar-free reciter approach is that adding more words to the vocabulary is simply done by dropping a new word sound file into Contents

    as an exercise for you to grow your blossoming scripting skills then consider:

    another thing we can do is check if the first word is a trigger and only recite phrases when triggered, so not to attempt to recite everything that might be typed. For example the trigger might be "\"

    "\ you are awesome" is recited
    "you are awesome" is not

    modding the above to add the check condition, is something like:

    if (llList2String(words, 0) == "\")
    {
    
    
    }


    the exercise for you is to figure out where this check condition goes in the script

     

    • Like 2
  12. yes it certainly makes it easier when you have a good knowledge of what sound words are available to you. You can more easily shape your texted phrases accordingly

    in this case the simple way to code this is to listen on the chat channel

    in the listen event dump the typed text to a list. Then loop thru the list and do an inventory lookup for a sound filename of the same spelling and then play it

    • Like 1
  13. from a purely scripting pov then is certainly possible to create a text-to-sound app

    from a user pov then the result will be variable when not all typed words have a matching sound file

    a way to do this is to create a dictionary of the words that do have a matching sound file, arranged in lists so that the words are grouped gramaticallyy:

    example

    list word1st = ["you", "are"];

    list word2nd = ["are", "you"];

    list word3rd = ["awesome","listening"];

    list sound1st= [youfile, arefile];

    list sound2nd = [arefile, youfile];

    list sound3rd = [awesomefile, listeningfile];

    the action phrases with this are:

    "you are awesome"

    "you are listening"

    "are you listening"

    "are you awesome"

    other phrases:

    "you you ..."

    "are are ..."

    in this dictionary approach then simple and knowable phrases in some grammatical order can be vocalised

     

    • Like 1
  14. parsing typed text is where we can begin thinking about this . A typed text example:

    "Hi! I found this awesome thing. Are you busy? Do you want to see it?"

    and other similar texts which can contain our action words which we want to ignore, when the texted conversation has no relationship to our app

    a more simple direct method is to listen on the channel for the whole action phrase. "You Are Awesome" and play a single soundfile that says "You Are Awesome"

    a sound file can be 10 seconds long. So even with a pause between each word then should be able to produce a vocalised phrasing that would fit and also sound good

     

    • Like 1
  15. 1 hour ago, Cindy Evanier said:

    I can deal with it.  I got my big girl knickers on 😭

    :)

    funny conversations: number eleventy

    me: holds my big girl knickers in my hand

    them: what you do that for?

    me: because I am going to put them on your head if you keep this up

    them: I would like that!

    me: then we both going to be happy

    :D

     

    • Haha 1
×
×
  • Create New...