Jump to content

Estelle Pienaar

Resident
  • Posts

    143
  • Joined

  • Last visited

Posts posted by Estelle Pienaar

  1. 6 hours ago, Quistess Alpha said:

    LSL is pass-by-value, and will never pass-by-reference. In other words, cycleList (content1); cannot change the value of content1. you have to return the value and do an assignment:

    list cycleList (list c_list) {
        if(llGetListLength(c_list) > 0)
        {
           string first_entry = llList2String(c_list, 0);
           c_list = llDeleteSubList(c_list, 0, 0);
           c_list += first_entry;
           llOwnerSay("Debugging. New list order is: " + llList2CSV(c_list));
           //return c_list; // returning here but not outside the if() will result in an error:
           // functions that return a value must return a value in all cases.
        }
        return c_list;
    }
    // later in the script:
    some_list = cycleList(some_list);

    Consider also:

    default
    {   state_entry()
        {   integer x=7;
            llOwnerSay("X="+(string)x);
            // scope-creation does not need a reason, like an if/while/for 
            {   integer x = 9; // removing 'integer' from this line leads to more 'expected' behavior.
                llOwnerSay("X="+(string)x);
            }
            // when scope is exited, x has its previous value: (because was re-declared in new scope)
            llOwnerSay("X="+(string)x);
        }
    }

     

    Thanks!

  2. Hello, I have made a user defined function that does not bring the same result as writing the function each time separately in the script. I might have made a mistake but don't see what it could be. The script snippet should cycle through a list by deleting the first value of a list and then adding it to the end of the list. In this example this is done with two separate lists at the same time:

    list content1 = ["1","2","3","4","5"];
    list content2 = ["a","b","c","d","e"];
    
    default
    {
        state_entry()
        {
           llSetTimerEvent(5);
        }
    
        timer()
        {
                    //script cycles the first list
                    if(llGetListLength(content1) > 0)
                            {
                            //script saves the first entry of the list
                            string first_entry = llList2String(content1, 0);
                            //script deletes the first entry of the list
                            content1 = llDeleteSubList(content1, 0, 0);
                            //script adds deleted first entry to the end of the list
                            content1 += first_entry;
                            llOwnerSay("Debugging. New list order is: " + llList2CSV(content1));
                            }
                    
                    //script cycles the the list
                    if(llGetListLength(content1) > 0)
                            {
                            //script saves the first entry of the list
                            string first_entry = llList2String(content2, 0);
                            //script deletes the first entry of the list
                            content2 = llDeleteSubList(content2, 0, 0);
                            //script adds deleted first entry to the end of the list
                            content2 += first_entry;
                            llOwnerSay("Debugging. New list order is: " + llList2CSV(content2));
                            }               
        }
        
        touch_end( integer num_detected )
        
        {
         llSetTimerEvent(0);   
        }
    }

     

    This snippet works as expected.

    Then I have made a user defined function but here the script will only delete the first entry of the list and put it at the end of the list at the very first iteration. After that, the list gets "stuck" and is not changed anymore at each timer event.

    cycleList (list c_list) {
        if(llGetListLength(c_list) > 0)
                            {
                            string first_entry = llList2String(c_list, 0);
                            c_list = llDeleteSubList(c_list, 0, 0);
                            c_list += first_entry;
                            llOwnerSay("Debugging. New list order is: " + llList2CSV(c_list));
                            }
    }
    
    
    list content1 = ["1","2","3","4","5"];
    list content2 = ["a","b","c","d","e"];
    
    default
    {
        state_entry()
        {
           llSetTimerEvent(5);
        }
    
        timer()
        {
                    //script cycles the first list
                    cycleList (content1);
                    
                    //script cycles the the list
                    cycleList (content2);
                                          
        }
        
        touch_end( integer num_detected )
        
        {
         llSetTimerEvent(0);   
        }
    }

    Can anyone spot the mistake, that I am making? I don't get it.

  3. On 2/11/2024 at 1:55 PM, Qie Niangao said:

    Yeah, that thread was from a couple years ago. As shown above, there's now a way to see more info about a playing animation in modern viewers. (That's the Linden PBR viewer, but the feature isn't that new so it's probably in most viewers currently used.)

    There's often talk of figuring out a way to inform the sim about these details too, but I suspect that will await broader changes to animation.

    Thank you!

    • Like 1
  4. I am planning to script an animation overrider. It would be great to let each animation play exactly as long as it is and not interrupt them after an x amount of time. However I cannot find any way to find out how long an animation is. Neither by script nor by any other means. That is certainly a big oversight by the Lab and the information certainly is available with the saved animation on the servers, but it does not get visible to the users. Or is there a way to make it visible?

  5. This script will switch on and off a projector. In order for the light to act like projector, the value for PRIM_FULLBRIGHT should be FALSE (unlike with point light):

    integer isLightTurnedOn;
    
    default
    {
        state_entry()
        {
            llSetPrimitiveParams([  PRIM_PROJECTOR, "TextureName", 3, 10, 0.5  ]);
        }
    
        touch_start(integer total_number)
        {
            isLightTurnedOn = !isLightTurnedOn;    
            vector COLOR_White  = <1.00, 1.00, 1.00>;
            
            if (isLightTurnedOn){
                llSetPrimitiveParams([
                    PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
                    PRIM_POINT_LIGHT, TRUE, COLOR_White, 1.0, 10.0, 0.6]);
    
                                }
            else{
     vector COLOR_White  = <1.00, 1.00, 1.00>;
                llSetPrimitiveParams([
                    PRIM_FULLBRIGHT, ALL_SIDES, FALSE,
                    PRIM_POINT_LIGHT, FALSE, COLOR_White, 1.0, 10.0, 0.6]);
                }
    
         }
    }

     

    • Like 1
  6. I am looking into projectors at the moment and the only LSL command that I can find is llSetPrimitiveParams and the flag [ PRIM_PROJECTOR ].

    Unlike the flag [ PRIM_POINT_LIGHT ] the prim_projector flag does not contain a boollean for FALSE or TRUE. Does that mean that there is no way to switch on or off a projector via touch and the only way to change it is by editing the object and do it in the edit window via the features tab? This would be a serious problem IMHO, now that PBR will look more dynamic and interesting by placing more projectors. But maybe I am overlooking something?

     

  7. Hello, I cannot find a function call that would change the access list of a parcel. However the existence of this script seems to suggest that it should be possible?
    Second Life Marketplace - Total Land Access! Prevent people ENTERING your land!

    My dream would be to script an object that checks if I am home and then restricts access to my parcel but allows access to anyone when I am not in the parcel. Doing this manually is a pain.

  8. Just one update: Everything works find apart from playing animations when getting from the Animation State "Standing" to Animation State "Turning", despite the animation being priority 5 and it being displayed in Animation info. Also I can not reproduce what I said before. It is not working in all viewers, there is no more difference between SL or BD viewer. I think I will open a JIRA.

  9. On 5/25/2023 at 9:17 PM, Quistess Alpha said:

    it's my working hypothesis that stopping an animation and then playing exactly the same one leads to issues.

    So after some more testing, my experience has been that it seems to be the contrary. The animations need to be stopped by the script, even if they should continue to run in another state and then be called again. That makes it much more reliable. If I do not stop the previous (same) animation from another animation state, it will often time not play in the new animation state (even if it is a higher priority). Moreover: If I test with the script with llGetAnimationList( key avatar ); , I will get a positive response saying that the animation is still playing, but it is not.

    One more remark: It is strange, that I can check for playing animations only by their keys while I can start animations only by the string name. Or is there a way to start an animation by its key and not its name? But this question is at this point rather theoretical, since the function llGetAnimationList seems not to be reliable anyway. I have given up on that step. I just stop the old animation and call for it in every animation state update, even if that is quite inefficient. But it works (for about 95% of animation state changes).

  10. 11 hours ago, NiranV Dean said:

    The difference is only between BD and SL then mainly. It probably stems from the fact that BD's default turn settings are lower, the official default settings for turning are 30° so before any "turning" animation plays you need to turn away ~30° in any direction from the initial "center" to which the avatar will then readjust and turn, while in BD the turn threshold is all the way down to 2° meaning essentially as soon as you even as much as think about rotating in any direction you will immediately see the avatar start the turning animation. However, there might be some desync happening here due to you checking for the animation rather than using the server-side AO features, i have never used the old AO system so i don't know what exactly it does and how it works but i'd assume it checks clientside, whenever the client is playing the turning animation, this coupled with BD playing them much more than other Viewers might cause a desync somehow (although it shouldn't as you are using the LSL play animation command which is a synced command, so everyone should see you play it).

    I am still playing around and changing the script, but I have not been able to fix this particular part. As soon as I think that the script cannot be changed anymore, I will make a full perm version of script and animations for you available, so that you can test yourself. It is very well possible that the difference stems from the lower threshhold before playing the turn. 

     

  11. 15 hours ago, Quistess Alpha said:

    from your code above it looks like those play the same animation. I haven't tested myself, but from other things you've mentioned, it's my working hypothesis that stopping an animation and then playing exactly the same one leads to issues. You could fix that by cleaning up your code a bit:

    string gCurrentAnimation; // the animation that we expect the avatar to be playing because we started it and have not stopped it.
    
    //...
    state_entry()
    {	llLinksetDataWrite("AnimState:Walking", "playThisAnimation");
        llLinksetDataWrite("AnimState:Turning Left", "PlayThisOtherAnimation");
        //...
        llSetTimerEvent(0.2);
    }
    //...
    timer()
    {   string animState = llGetAnimation();
        string wantToPlay = llLinksetDataRead("AnimState:"+animState);
        if(wantToPlay!=gCurrentAnimation)
        {   if(gCurrentAnimation) llStopAnimation(gCurrentAnimation);
            if(wantToPlay) llStartAnimation(wantToPlay);
            llOwnerSay("AnimState is: "+animState+"\n"+
               "Changing from '"+gCurrentAnimation+"' to '"+wantToPlay+"'.");
            gCurrentAnimation = wantToPlay;
        }
    }

    or so.

    Thank you very much, I will look into it! 

    What I can already say is, that it really works differently in the Second Life viewer. There I don't have problems when switching between turns and . But Black Dragon viewer never plays it in this case. On the other hand the Black Dragon viewer almost always shows the priority 4 walking animation (I'd say 95% of the time it works) while the Second Life viewer almost never shows it (I'd say 30% of the time it works).

    I did not expect such differences between viewers. That means that I  additionally might have to create another priority 5 animation, probably.    

  12. You are right, one animation for walking and running with the wand was only priority 4. The other one for standing is priority 5.

    I have set the timer to 0.25 seconds instead of 0.1 seconds. Now it works quite ok. 

    However I realised that if I switch from turning left to turning right or from turning right to turning left, it will always fail to play (despite this animation being priority 5).

    If I check with 

                list anims = llGetAnimationList(owner);
                if(~llListFindList(anims, check))

    if the animation is playing during the turn it gives me a positive, but it is not visible.

    It might be a problem specific to the Black Dragon viewer. Will check that later. 

  13. While writing this post, I had the idea that the script might get confused that I use the same animation for "Standing" and "Turning". So I added another copy of the same animation with a different name. I renamed the two instances of the same animation "wand-standing" and "wand-turning". Now the switch between "Standing" and "Turning works. However the following problem remains:

    (1) The "wand" animations plays reliably with "standing".

    (2) The "wand" animation plays approximately 4 out of 5 times when "walking" or "running".

    (3) The "wand" animation plays NOW approximately 4 out of 5 times when "turning".

     

    EDIT: I made now 5 instances of the 2 animations as "wand-walk", "wand-run", "wand-stand", "wand-turn-l", "wand-turn-r" to make sure that the reason for the animation sometimes not starting in some animation states is not due to using the same animation with the same name in different states. But the problem remains.

  14. So in order to have the wand holding up in a mele fight, I have created wand holding animations that are added to the animations of the AO. These animations should be played when walking, running, standing and turning. The following snippet is what I have so far.

    It does reliably realize when the animation state changes and always gives the correct message in chat, e.g. "You started walking". However the animations are not played reliably. I don't think that it is a problem of the animation priorities because they do play for all animations, just not all of the time.

    Here is what I am experiencing:

    (1) The "wand" animations plays reliably with "standing".

    (2) The "wand" animation plays approximately 4 out of 5 times when "walking" or "running".

    (3) The "wand" animation plays only when turning when coming from a "walking" or "running" state. It never plays when I have been "standing" before.

    It's a riddle why the changes of the animation states are reliably called out in chat, but the animations are not played reliably.

    key ownerK;
    integer timernumber;
    integer movementstate;
    string gLastAnimation;
    string newAnimation;
    string Lanimation = "wand-attackV2";
    
    default
    {
        state_entry()
        {
            ownerK = llGetOwner();
            llSetTimerEvent (0.1);
        }
    timer ()
        {
    
    if (gLastAnimation == "0") {gLastAnimation = llGetAnimation(ownerK);}
    else
      {
    newAnimation = llGetAnimation(ownerK);
    if (gLastAnimation != newAnimation) { 
    
     if (newAnimation == "Walking") 
                {
                llStopAnimation (Lanimation);
                llStartAnimation("wand- walkV3b");
                llOwnerSay("You started walking");
                gLastAnimation = "Walking";
                Lanimation = "wand- walkV3b";
                }
    
        else if (newAnimation == "Running") 
    
                {
                llStopAnimation (Lanimation);
                llStartAnimation("wand- walkV3b");
                llOwnerSay("You started running");
                gLastAnimation = "Running";
                Lanimation = "wand- walkV3b";
                }
     
        else if (newAnimation == "Standing")
    
                {
                llStopAnimation (Lanimation);
                llStartAnimation("wand-attackV2");
                llOwnerSay("You are standing");
                gLastAnimation = "Standing";
                Lanimation = "wand-attackV2";
                }
        
        else if (newAnimation == "Turning Left")
                {
                llStopAnimation (Lanimation);
                llStartAnimation("wand-attackV2");
                llOwnerSay("You are turning left");
                gLastAnimation = "Turning Left";
                Lanimation = "wand-attackV2";
                }
     
        else if (newAnimation == "Turning Right")
                {
                llStopAnimation (Lanimation);
                llStartAnimation("wand-attackV2");
                llOwnerSay("You are turning right");
                gLastAnimation = "Turning Right";
                Lanimation = "wand-attackV2";
                }
              }  
    }

     

    wand.png

  15. 1 minute ago, Wulfie Reanimator said:

    For other objects, like your NPCs, you can account for the sensor by building the object in such a way that the root/link points in the correct direction.

    Also, instead of doing 45 or 180 degrees, why not 90? That way you'd scan only the correct (front) side of the object.

    Thanks a lot for the first part of the response. Indeed you are right that the sensor does not originate from the attached prim, but from the center of the avatar. The lsl Wiki could be more specific at this point. But now I know that a simple sensor called from an attached will be sufficient for the player agent. I also tested and the PI/4 arc is not sufficiently wide. It needs to be PI/3. So for that part my headaches are solved!

    I don't however understand the second part of your response. This would only work if the NPC does not move and rotate at all, wouldn't it? But in the concept of the game the agent and the NPC object will move and rotate constantly towards each other. So also the sensor that originates from the NPC would have to rotate with the NPC. But an LSL sensor originating from an object would constantly only point towards the x-axis, ignoring any rotation of the object. Or do I get something wrong? 

  16. All mele combat systems that I have ever tried in SL (I have to admit that I haven't tried many) where very clunky. Mostly they consisted of trying to move in front of target and click the left mouse button as often as possible. There are no real movement combinations for attacks or defense.

    As I have the project to script a mele combat system, I would like to see what my options are. The big problem for implementing more refined combat moves seems to be that it is impossible to assign other keys than the typical movement keys and the two mouse buttons to be detected by an LSL script. But the movement keys are already needed for the movement during a fight. So if I wanted to assign an attack to the key "G" on the keyboard and have it recognised by the script, it is literally impossible.

    Or are there any practical workarounds?

    As far as I can see my only options are:

    (1) measuring how long the left mouse button is clicked and assign two different attacks depending on if it is clicked long or short.

    (2) Creating a HUD with different buttons and the player would have to click different buttons for different attacks. Not userfriendly at all.

    (3) Assign attacks and dodging to keys that are not frequently used during normal SL movement.

    This could be used for dodging:

    CONTROL_DOWN 0x00000020

    Move down control (PgDn or C)

    This could be used for attack combinations:

    CONTROL_LEFT 0x00000004 4 move left control (shift + A or left arrow)
    CONTROL_RIGHT 0x00000008 8 move right control (shift + D or right arrow)

    Why has Linden Lab never implemented the possibility to llTakeControl of another keyboard key that is not used for movement? That would have opened up so many opportunities, not just for combat systems, but also other interactive content. It's a riddle to me why Linden Lab sees all the clunky mele combat systems in SL and says: Yes, that is how content on our platform should be. Creators clearly have all the tools they need at their disposal. 😅

    Or am I missing anything?

         
         
×
×
  • Create New...