Jump to content

Isobeast

Resident
  • Posts

    68
  • Joined

  • Last visited

Posts posted by Isobeast

  1. When I first fell into SL, it was probably ten years ago, I barely earned ten lindens an hour and it was more like slavery, I had to stand in one place and perform some stupid dance, while I had to watch the advertisements on the walls and it was impossible to get out, as some kind of reset mechanism was triggered. Probably for this they began to prohibit the so-called camping.


    But it was still very interesting to study the possibilities of this world, one might say, in the best years!


    I do not know how things are with this now, but I really sympathize with novice players.


    The greatest success here is likely to be achieved mainly by people with professional skills who perceive SL as a commercial platform.
    Although some skills can be acquired from scratch here in SL, it takes a lot of strength and perseverance.

     

    So yes, it’s difficult for beginners, probably, if you don’t invest real money. ;)

    • Like 1
  2. I generally prefer not to read the review, they create a lot of tension in me, like a lottery, so I turned off all notifications from the market. Of course, it's always nice to read good reviews, but bad reviews usually make me very upset. If a person really needs help, they understands that they need to contact me first and not write an angry review. Therefore it saves the nervous system. I advise everyone. :D

     

    Besides, I am doing stuff not for reviews mostly.

    • Like 1
  3. On 10/29/2021 at 11:02 AM, Qie Niangao said:

    Sorry, I realize it's a little late now, but here's a simple example. (Doesn't do any of the stream control stuff.)

    
    setSeat(integer enabled)
    {
        llSetClickAction(llList2Integer([CLICK_ACTION_TOUCH, CLICK_ACTION_SIT], enabled));
        llSetLinkPrimitiveParamsFast(LINK_THIS, [ PRIM_SCRIPTED_SIT_ONLY, !enabled ]);
    }
    
    default
    {
        state_entry()
        {
            llSitTarget(<0,0,0.5>, ZERO_ROTATION);
            setSeat(FALSE);
        }
        touch_start(integer total_number)
        {
            key toucher = llDetectedKey(0);
            if (llDetectedGroup(0))
            {
                llRegionSayTo(toucher, 0, "This seat is available to a group member for 10 seconds.");
                setSeat(TRUE);
                llSetTimerEvent(10.0);
            }
            else
                llRegionSayTo(toucher, 0, "Perhaps you want to change your active group?");
        }
        changed(integer change)
        {
            if (CHANGED_LINK & change)
            {
                key newestSitter = llGetLinkKey(llGetNumberOfPrims());
                if (NULL_KEY == newestSitter)   // nobody seated
                    return;
                else
                if (llSameGroup(newestSitter))  // group member sitting
                    setSeat(FALSE);
                else
                    llUnSit(newestSitter);  // non-member tried to sit while seat enabled
            }
        }
        timer()
        {
            setSeat(FALSE);
        }
    }

    Among the crude simplifications, a group member's touch enables the seat for any one group member, not restricted to the toucher.

    Thank you very much! Your version works too now! 👍

  4. 1 hour ago, Qie Niangao said:

    the PRIM_SCRIPTED_SIT_ONLY could reduce confusion for non-group members: They touch and nothing happens, but group members enable seating. There still should to be a test in CHANGED_LINK in case a non-group member sneaks in between when the group member touches and when they sit.]

    Could you please give an example of using this method? I have not found any wiki examples and have never used it myself.

  5. I managed to do something with the changed event! 👍

    but now if you passed the check once, you can sit down over and over again without checking. shouldn't the timer be reset OkToSit to NULL_KEY? I even added a separate reset when getting up, but it didn't help.

     

    So far with the changed event ...

    not sure if this is ok. please correct me if something is wrong !!

        changed(integer change)
        {
            if (change & CHANGED_LINK)
            {
                llSetTimerEvent(0);
                
                key sitter = llAvatarOnSitTarget();
                if (sitter != OktoSit)
                {
                    llUnSit(sitter);
                    llSetAlpha(1.0, ALL_SIDES); // Show prim
                    llWhisper(0, "Please touch me first to perform the group check");
                }
                else if (sitter != NULL_KEY)
                {
                    gListener = llListen(channel, "", sitter, "");
                    llWhisper(0, "Enter the URL of your stream in channel 10. Example: '/10 http://streamurl.com:0000'");
    
                    llRequestPermissions(sitter, PERMISSION_TRIGGER_ANIMATION);
                    OktoSit = NULL_KEY;
                }
                else
                {
                    if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)
                    {
                        llListenRemove(gListener);
    
                        if (animation)
                        {
                            llStopAnimation(animation);
                        }
    
                        llSetAlpha(1.0, ALL_SIDES); // Show prim
    
                        // Read the default URL from the object description:
                        key default_url = llGetObjectDesc();
    
                        llSetParcelMusicURL(default_url);
                        llWhisper(0, "The parcel stream returned to the radio at the URL: " + (string)default_url);
                    }
                }
            }
        }

     

  6. 10 minutes ago, Mollymews said:

    set the listener to only listen for the sitter. So naughty people can't interfere with the sitter, by changing the stream

    gListener = llListen(channel, "", sitter, "");

    Oh this is a very valuable remark, thank you! 👍

     

    • Like 1
  7. And here is the touch event

        touch_start(integer num_detected)
        {
            if (llDetectedGroup(0) == TRUE)
            {
                llSetTimerEvent(10);
                OktoSit = llDetectedKey(0);
    
                llWhisper(0, (string) OktoSit + "You have 10 seconds");
            }
            else
            {
                OktoSit = NULL_KEY;
                llWhisper(0, "Wrong group tag");
            }
        }

     

  8. 13 hours ago, Profaitchikenz Haiku said:

    The plan sounds OK.

    have a global variable key OktoSit intiialised to NULL_KEY;

    Inside the touch event,

    test llDetectectedGroup. If True, set a timer for ten seconds, and set llDetectedKey value as the global variable OktoSit;

    if FALSE, set global variable OktoSit to NULL_KEY

    If the timer goes before any changed event, set OkoSit to NULL_KEY

    Inside changed, in changed link, cancel any timer then test the value for llAvatarOnSitTarget. If it is Not NULL_KEY, then check if it is the same as OktoSit. If different, unsit whoever it was.

    If somebody just right-clicks and sits without first touching, OktoSit will be NULL_KEY and so they will get thrown off. If they don't know they must be in the same group they might keep on trying, so when you unsit somebody, whisper a message such as "Please touch me first to perform the group check" Or have a sign or hovertext advising them.

    Don't forget that llAvatarOnSitTarget will return NULL_KEY when somebody has just got up, so seperate thoe two conditions carefully.

     

    17 minutes ago, Qie Niangao said:

    Is it important to the scenario that there be two separate actions here, the touch and then the sit? If it's just as good for touch to automatically seat group members, there's a handy function llSitOnLink() that could go in a touch-related event handler, conditionalized on llDetectedGroup(), and with seating on the object itself limited by PRIM_SCRIPTED_SIT_ONLY.

    (Incidentally, in addition to llDetectedGroup(), similar functionality is offered by llSameGroup() inside function or events (such as changed) where Detected functions aren't available. It's also possible to test for different groups, but that's tangential even to this tangent.)

    thank you very much! I decided to try what the Prof advised, but nothing came of it. I understand logically, but I cannot transfer it to the script. Here are my changed and timer events.

     

    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            llSetTimerEvent(0);
    
            key sitter = llAvatarOnSitTarget();
    
            if (sitter != NULL_KEY)
            {
                if (sitter == OktoSit)
                {
                    gListener = llListen(channel, "", "", "");
                    llWhisper(0, "Enter the URL of your stream in channel 10. Example: '/10 http://streamurl.com:0000'");
    
                    llRequestPermissions(sitter, PERMISSION_TRIGGER_ANIMATION);
                }
                else UnSit(sitter);
            }
        }
        else
        {
            if (llGetPermissions() & PERMISSION_TRIGGER_ANIMATION)
            {
                llListenRemove(gListener);
    
                if (animation)
                {
                    llStopAnimation(animation);
                }
    
                llSetAlpha(1.0, ALL_SIDES); // Show prim
    
                // Read the default URL from the object description:
                key default_url = llGetObjectDesc();
    
                llSetParcelMusicURL(default_url);
                llWhisper(0, "The parcel stream returned to the radio at the URL: " + (string) default_url);
            }
        }
    }
    
    timer()
    {
        OktoSit == NULL_KEY;
        llSetTimerEvent(0);
    }

     

  9. 42 minutes ago, Profaitchikenz Haiku said:

    Not that I know of.

    Go back to where you were going to add the group-check and have another go.

    If the toucher is also the sitter, then do the llDetectedGroup() check. If that check is false, unsit the sitter.

    If nobody is sitting but you get a touch, what is your plan? Ignore the touch? Tell them to sit? 

    The plan was this: the avatar clicks on the prim, and if the group matches, then the avatar has, say, ten seconds to sit down. if the group does not match, then there is no way to sit. and then I realized that the avatar can also sit with the right mouse button ... and then I got stuck.

     

  10. 19 hours ago, Xiija said:

    to check for a valid stream, you might do something like...

     listen(integer channel, string name, key id, string message)
        {   string stream = llStringTrim( message, STRING_TRIM );
            if( llGetSubString( stream, 0, 3) != "http")
            {   llSay(0, "Invalid Stream URL: " + message);
            }
            else
            {   llSay(0, "Setting Stream to:  " + message);
            }
        }

     

    Thank you very much! Your examples were very useful to me!

     

    Another question. I'm trying to add a group check if (llDetectedGroup(0)), and to use llUnSit() if not in group, but none of the events seem to work for this: changed, listen and run_time_permissions ... What to do in this case?

     

    • Like 1
  11. 1 hour ago, Profaitchikenz Haiku said:

    On this matter, I have no experience at all. If there's a channel playing Buxtehude I'll experiment.

    Just a guess, but you could try passing such an invalid string and seeing hat the function return codes are, that' most likely where youre going to get some indication of what didn't agree with the recieveer.

    Thank you very much! Now it is clear!

  12. This script looks very useful!

    https://community.secondlife.com/forums/topic/32812-basic-pose-ball-script/

    ... But how do you prevent the error message from appearing if there is no animation in the prim or the animation is named incorrectly?

    Is it possible to simply pop up a message in the chat instead of it stating that "the animation is missing or is incorrectly named ... "

     

    Oh, and what to do if the URL entered is invalid, or the text is not a URL at all?

  13. 3 hours ago, Qie Niangao said:

    The parcel audio stream can be set by a script owned by the same account that owns the land. (That means on group-owned land, the script needs to be in a group-deeded object.)

    Then it's up to the script to get stream links from wherever it's handy in the application. If, for example, literally anybody should be able to set the stream to anything at all, the script could take input from llTextBox() perhaps in a touch_start() event handler, then maybe llEscapeURL() of the response string it gets in listen(), and llSetParcelMusicURL() with that tidied-up string.

    Another common scenario is for the stream-changing script, owned by the landowner, to communicate with "remote control" scripted objects owned by tenants; there are surely commercial products that do this, and maybe some open source scripts.

     

    3 hours ago, Mollymews said:

     

    the method to do this is: http://wiki.secondlife.com/wiki/LlSetParcelMusicURL

    if you want the others to be able to set the parcel music to anything they want then the script can offer a llTextBox for them to type in the url

    edit: what Qie said

    Thank you very much! Definite progress has been made on this issue, thanks to you!

     

    Could you please also help to make the text box activate when the avatar is sitting on a prim?

    And how to determine the moment when the avatar gets up to change the URL to the default one?

  14. On 10/24/2021 at 5:35 PM, Madelaine McMasters said:

    Okay, here's the control panel for the weather system. Apply the texture to a cube, resize it to taste, and drop the script inside. I recommend making the cube three times higher than it is wide and/or deep. You can squish it flat or bury it in a wall to hide unwanted faces. You can also make unwanted faces transparent. Though you won't see them, they'll still respond to touch.

    857672013_WeatherControlPanel.jpg.cbaf7dafe7cbfbfceed04f797fbf11a9.jpg

    Touching the raindrop button will start any weather emitters in the region, using the rain texture and its associated particle parameters.
    Touching the snowflake button will start any weather emitters in the region, using the snow texture and its associated particle parameters.
    Touching the power button will stop any weather emitters in the region.
     

    Here's the script:

    integer channel = 33; //Using a positive channel number allows control via chat commands, but is less secure.
    
    //These two constant factors are used to scale the returned touch position such that they can be used as indices.
    //This is a single column interface, so "numberofColumns" isn't really needed.
    //I've kept it to allow easy expansion of the interface to more buttons.
    integer numberOfColumns = 1;
    integer numberOfRows    = 3;
    
    integer scanTime = 10; // Look for avatars within sensorRange every scanTime seconds.
    integer sensorRange = 60; // Anyone within this distance (in meters) of the control panel will trigger the weather system.
    
    string weather; // This string holds the desired state of the weather system, when enabled by nearby avatars.
     
    doWeather(){
        llRegionSay(channel, weather);
    //    llOwnerSay(weather);
    }
    
    default
    {
        state_entry(){
            weather="off";
            llSensorRepeat("", "", AGENT_BY_LEGACY_NAME, sensorRange, PI, scanTime);
        }
        
        sensor(integer num_detected){ // There's someone nearby to see the weather, so make some.
            doWeather();
        }
        
        no_sensor(){	// There's nobody nearby to see the weather, turn it off to avoid bothering others.
            if(weather != "off");
            llRegionSay(channel, "off");
        }
        
        touch_start(integer total_number)
        {
            vector  touchST     = llDetectedTouchST(0);
     
    //      touchST.x goes from 0->1 across the face from the left to the right
    //      touchST.y goes from 0->1 up the face from the bottom to the top
     
            integer columnIndex = (integer) (touchST.x * numberOfColumns);
            integer rowIndex    = (integer) (touchST.y * numberOfRows);
     
    //        llOwnerSay("ST grid (" + (string)columnIndex + ", " + (string)rowIndex+")");
                                
            if(columnIndex==0){ // Not needed for this single column control panel
                if(rowIndex==0){
                    weather="off";
                }
                else if(rowIndex==1){
                    weather="snow";
                }
                else if(rowIndex==2){
                    weather="rain";
                }
                doWeather();
            } // Not needed for this single column control panel
        }
    }

    Rather than place these things out on the lawn in front of my snow cabin, which is only a temporary rental, I'll send them to anyone who asks for copies.

    Remember, this is a quick hack. There's probably a better way to do it. I could see adding a few more commands to set parameters like RADIUS and AGE in the particle emitters, so you could adjust them to your liking without having to dig into each and every emitter's script. You'd place the parameters in the control panel and message them out to the emitters.

    ETA: I've added comments and the "scanTime" variable to the script, to improve readability and comprehension. Hopefully it still compiles!

    Wow! I tested it and I like it! Thanks! 

    Conveniently, this switch doesn't need separate buttons. 👍👍👍👍👍

    Snapshot_001.png

  15. On 10/22/2021 at 7:59 AM, Madelaine McMasters said:

    Okay, here are the rain/snow textures and the script for the particle emitter (name them "snow" and "rain"). I will make this all available in-world shortly if you don't want to go through the hassle and cost of uploading all the bits.

    The textures below are white on transparent backgrounds, so you can't see them, but if you click in the blank white spaces below, you'll catch them. Rez a cube on the ground and drop the script and textures into it. Type "/33 rain" or "/33 snow" to get rain or snow. Type "/33 hide" to make the cube invisible and "/33 show" to make it reappear. The particles are emitted upward in an fan shaped arc 15m above the ground and immediately start falling. They'll vanish a few meters below the cube, so could be used in a skybox if there's nobody right under you. The particles are 4m wide, so the sheet of rain/snow will be that thick and about 30m wide.

    It's easiest to see the emission pattern at "midnight" as the textures are set to full bright (emissive mask = TRUE).

    In my homes, I place the emitters just over 2m away from the outside walls, turned so the sheet is parallel to the wall. If I have a yard, I'll set a second emitter at the edge of it so I still see rain or snow if I walk outside.

    If you want a taller sheet of particles, increase the emitter RADIUS. You'll also have to increase the particle AGEs to make sure they survive the longer fall. If you want a wider spread, increase ANGLE_BEGIN. There might have been a good reason I chose PI/7, probably to avoid the top of the sheet looking too curved.

    In the next day or two, I'll post the script for a central controller that senses nearby avatars and starts any emitters in the region when there's someone present and stops them when nobody's there. I implemented this to reduce annoyance to others when I'm not around.

    snow:

    snow.png.ecff421c59df12439d0e7ac0dba93f54.png

    rain:

    rain.png.b932cb7dc5e4ff6da98e81a39d7f2db5.png

    Script:

    integer chan = 33;
    integer listen_handle;
    
    mySetParticles(string kind) {
        
        string TEXTURE;
        float AGE;
        float RATE;
        integer COUNT;
        vector ACCEL;
        float  SPEED_MIN;
        float  SPEED_MAX;
        float  END_ALPHA;
        
        if(kind == "rain"){
            TEXTURE = "rain";
            AGE = 10;
            RATE = 0.03;
            COUNT = 3;
            SPEED_MIN = 3;
            SPEED_MAX = 3;
            ACCEL = < 0.00, 0.00, -1.0 >;
            END_ALPHA = 1.0;
        }
        else if(kind == "snow"){
            TEXTURE = "snow";
            AGE = 20;
            RATE = 0.05;
            COUNT = 1;
            SPEED_MIN = .01;
            SPEED_MAX = 1;
            ACCEL = < 0.00, 0.00, -.1 >;
            END_ALPHA = 1;
        }
        else return;
    
        vector  START_SCALE = < 4, 4, 0 >;
        vector  END_SCALE = < 4, 4, 0 >;
        vector  START_COLOR = < 1, 1, 1 >;
        vector  END_COLOR = < 1, 1, 1 >;
        float   START_ALPHA = 0.0;
        integer INTERP_COLOR = TRUE;
        integer INTERP_SCALE = TRUE;
        integer EMISSIVE = TRUE; // this makes rain/show much more visible
        
    
        integer PATTERN = PSYS_SRC_PATTERN_ANGLE;
        float   RADIUS = 15; // 0.00
        float   ANGLE_BEGIN = PI/7; // 0.00
        float   ANGLE_END = 0.0; // 0.00
        vector  OMEGA = < 0.0, 0.0, 0.00 >; // < 0.00, 0.00, 0.00 >
        float   LIFE = 0;  // 0.0
    
        integer      FOLLOW_SRC = FALSE;
        integer FOLLOW_VELOCITY = TRUE;
        integer            WIND = FALSE;
        integer          BOUNCE = FALSE; 
        integer      TARGET_POS = FALSE;
        key              TARGET = llGetKey();
                         
        list particle_parameters = [
                PSYS_PART_FLAGS, ( 
                    (        EMISSIVE * PSYS_PART_EMISSIVE_MASK ) | 
                    (          BOUNCE * PSYS_PART_BOUNCE_MASK ) | 
                    (    INTERP_COLOR * PSYS_PART_INTERP_COLOR_MASK ) | 
                    (    INTERP_SCALE * PSYS_PART_INTERP_SCALE_MASK ) | 
                    (            WIND * PSYS_PART_WIND_MASK ) | 
                    (      FOLLOW_SRC * PSYS_PART_FOLLOW_SRC_MASK ) | 
                    ( FOLLOW_VELOCITY * PSYS_PART_FOLLOW_VELOCITY_MASK ) | 
                    (      TARGET_POS * PSYS_PART_TARGET_POS_MASK ) ),
                PSYS_PART_START_COLOR,     START_COLOR,
                PSYS_PART_END_COLOR,       END_COLOR,
                PSYS_PART_START_ALPHA,     START_ALPHA,
                PSYS_PART_END_ALPHA,       END_ALPHA,
                PSYS_PART_START_SCALE,     START_SCALE,
                PSYS_PART_END_SCALE,       END_SCALE, 
                PSYS_SRC_PATTERN,          PATTERN,
                PSYS_SRC_BURST_PART_COUNT, COUNT,
                PSYS_SRC_BURST_RATE,       RATE,
                PSYS_PART_MAX_AGE,         AGE,
                PSYS_SRC_ACCEL,            ACCEL,
                PSYS_SRC_BURST_RADIUS,     RADIUS,
                PSYS_SRC_BURST_SPEED_MIN,  SPEED_MIN,
                PSYS_SRC_BURST_SPEED_MAX,  SPEED_MAX,
                PSYS_SRC_TARGET_KEY,       TARGET,
                PSYS_SRC_ANGLE_BEGIN,      ANGLE_BEGIN, 
                PSYS_SRC_ANGLE_END,        ANGLE_END,
                PSYS_SRC_OMEGA,            OMEGA,
                PSYS_SRC_MAX_AGE,          LIFE,
                PSYS_SRC_TEXTURE,          TEXTURE
            ];
            
        llParticleSystem( particle_parameters );
        if ( (AGE/RATE)*COUNT > 4096) {
            llOwnerSay( "Too many particles, decrease AGE and/or COUNT and/or increase RATE.");
        }
    }
    
    default{
        
        on_rez(integer param){
            llResetScript();
        }
        
        state_entry() {
            listen_handle = llListen(chan, "", NULL_KEY, "");
            llOwnerSay("Weather System Starting");
        }
        
        listen( integer channel, string name, key id, string message ){
            if(message=="rain" || message == "snow"){
                mySetParticles(message);
            }
            else if(message=="off"){
                llParticleSystem([]);
            }
            else if(message=="hide"){
                llSetAlpha(0,ALL_SIDES);
            }
            else if (message=="show"){
                llSetAlpha(1,ALL_SIDES);
            }
        }
    }

     

    Many thanks! Just tried your script, it's perfect!
    It was such a rainy day, very impressive! :)

     

    Snapshot_007.png

  16. 7 hours ago, Drake1 Nightfire said:

    If you want the truth, crappy. 

    My dad is in the hospital after having surgery that may be colon cancer, which his father died from. My youngest daughter keeps passing out for no reason and none of the doctors have a clue what's going on, she currently has 6 bruised ribs from the last time. My eldest daughter has severe pain in her legs, near constant migraines that her prescriptions are no longer helping and again the docs have no idea why. I have a pair of kidney stones that could be used for a house foundation. And my wife is barely keeping things together from all of the stress. 

    How are you doing?

    I am fine, thank you! :)

    • Confused 1
  17. 52 minutes ago, Madelaine McMasters said:

    Go visit the LM I posted and set midnight, to get a sense for what the system looks like. Give me a few days (I'm not in world much) to find the more capable system that also does rain. It was a quick hack, done years ago, and is certainly ripe for improvement.

    Really looks very nice!

    Untitled.png

    • Thanks 2
  18. 5 minutes ago, Cinnamon Mistwood said:

    I fear you're about to be roasted, so buckle up.

    I'm doing well today.  You?

     

     

    1 minute ago, Garnet Psaltery said:

    Very well, thank you, and you?

     

    1 minute ago, Sid Nagy said:

    Truth or standard return?

    Let's keep it standard:
    Fine, thanks, and you?

    I am fine, thank you! :)

    • Like 2
×
×
  • Create New...