Jump to content

Sylvia Wasp

Resident
  • Content Count

    208
  • Joined

  • Last visited

Posts posted by Sylvia Wasp


  1. 3 hours ago, janetosilio said:

    It’s the second most worn body.


    Honestly, I don’t even pay attention to group notices. I treat them like spam, close the box immediately when they pop up. I’ve been doing that for years.
     

    The best way to advertise now is through social media. Apparently, they are cracking down on Flickr, but that’s usually where I find out who has things I might be interested in. You can post ads, but not links.

    Well, I would disagree on "second most worn body" it depends on how the pollster makes the poll.  🙂

    The numbers also show that Belleza Freya is pretty much the only one of the three Belleza's that's still popular with designers (because sales).  

    Anyway, Belleza users seem to be different from Tonic/Maitreya/SLink users and probably always will be.  

    I WANT to make clothing for Belleza Freya, and I AM making clothing for Belleza Freya, I'm just saying that they are making it much harder than it should be to make Belleza users aware of that fact.  

    They just don't seem to have even basic infrastructure for promoting their brand. 

    Sylvia


  2. 3 hours ago, Syn Anatine said:

    Are these groups owned by the Belleza creator? If no, then....why take it out on the brand? That doesn't make a lick of sense.

    I'm not "taking it out" on anyone.  You're just trying to make me sound angry or unreasonable.  

    I'm just saying that every body type has groups precisely for this sort of thing, that Belleza seems to have one too, but ... that there seems to be basically "no one home" when I ask about advertising etc. 


  3. I know the title is a bit cheeky, but seriously ... 

    I have a small store where I make clothing for (female) avatars and I recently decided to expand the body types I support. I *had* been only supporting Tonic (the best mesh body) and Maitreya (the most popular mesh body), but I decided to expand my repertoire to include SLink, and because it's still very popular (apparently) .... Belleza Freya.  

    I then went about joining all the groups and trying to find out which ones I could use to announce products in. I found out how to do it with SLink right away (they have rules for it, like everything, lol) but  it seems that Belleza is completely lacking

    There are lots of Belleza groups, but only three with large followings that seem like the places to announce new product.  I tried asking in the groups, I tried finding out the owners of the groups and IM'ing them, and eventually I even dropped notecards explaining myself to the owners of these groups.  Two of them even say in the group description that you can "apply" for permission to post notices in the group if you are a creator and I've done that.  

    What I've got back ... (and this is weeks ago!), is sweet F-all.  Nothing. Nada. No contact.  

    I spent many days updating everything I make to support Belleza Freya and now I'm thinking I probably shouldn't have bothered.   

    Sylvia.  


  4. 1 hour ago, Wulfie Reanimator said:

    "Micro" mesh is just regular mesh with a trick. For example, look at my beautiful jewelry part:

    ba3931a811.png

    Marvelous, I know. The problem is that this part can only be sized down to 0.01 because of SL limits. That's too big! But what if I put a box around my work that's twice the size?

    ec1f3e0012.png

    It can still be sized down to 0.01, but now the detail I want people to actually see is 0.005 in scale!

    So what happens when I try to scale this up? Well, SL has a maximum scale of 64. That means people can only see the inside at a size of 32 meters.

    Cool explanation as always.  🙂 

    Pictures really help too.  

    Sylvia 


  5. 1 minute ago, Chic Aeon said:

    Keep in mind that if you buy "micromesh" parts EACH PART will count as half a land impact, making your items VERY "primmy". Most jewelry is made as a single mesh item WITHIN 3D software.  So your base plan may be faulty :D. Just a warning.

     

    Personally I wouldn't buy anything from a seller with such a nasty message. 

    Thanks for the heads up, but I thought that worn items don't count as much as rezzed prims, no?

    I mean back in the day, everyone was walking around with jewellery made out of hundreds and hundreds of individual prims (ie - hundreds of LI if rezzed on the ground).    

    Sylvia


  6. I'm considering getting into making jewellery and I need to buy some FP micro mesh for that purpose.  The seller in question has a (rude IMO) 'no questions, no support, no refunds, no returns' kind of policy so I can't ask him the question before the purchase. 

    The (stupid) question is ... I know "micro-mesh" is designed to be small, but how big can it actually get?  

    Like, can I buy a "micro-mesh" item and then just drag the handles out until it's as big as a house?  What would happen?  What's the essential difference between "micro-mesh" and regular  mesh anyway? 

    Okay so I guess that's two questions lol. 

    Sylvia 🙂


  7. 19 hours ago, Mollymews said:

    lets look at this from a different pov. A pov of mathematics that can lead us into a situation that we have no reason to be in

    we have a script which listens on a channel, where the possible number of channels is 2 ^ 32 - 1 (not counting the debug channel) = 4,294,967,295

    the script listens to a named object. A name which can be length 1 to 63 where there are 94 possible ASCII-7 chars to choose from

    length 1 = 94 ^ 1
    length 2 = 94 ^ 2
    length 3 = 94 ^ 3
    ...
    length 62 = 94 ^ 62
    length 63 = 94 ^ 63

    add them all up: 2.0497E+124

    multiply this by the channels: 2.0497E+124 * 4.29E+09

    the result is: 8.80E+133.  A number that is 134 decimal numerals long.  Which is a really big number

    and because it is we think that the mathematical probability of our script colliding with another script is so tiny that we are not going to worry about it

    not worrying about it, is like betting that we are not going to win the Lotto. A thing about large numbers, is that somebody does eventually win the Lotto. We are gambling that it will never be us

    what we should be thinking is that our script is not a lottery ticket. Is a script to change the textures on our object/garment

     

    thanks Molly 🙂

    • Like 1

  8. On 2/2/2020 at 11:35 AM, Mollymews said:

    adding to the conversation

    it isn't greifers so much we worry about, is all the other people who make appliers

    the goal is to make our code as efficient as possible. Leaving communications holes in our code, makes our code inefficient

    looking at the communications model for your (Sylvia) objects and HUDs so far

    key2chan - gives each of our customers the widest possible opportunity  to be on a separate channel

    listen for named HUD - as we can uniquely name our products, then no two different products of ours will ever cross talk

    llRegionSayTo(llGetOwner().... - our HUD will never send a message to a script owned by another  person

     

    adding to this

    check for Owner - excludes any message from a scripted object with the same name as our HUD,  on the same Key2Chan channel, owned by someone else

    check for Creator - excludes any message from a scripted object with the same name as our HUD, on the same Key2Chan channel, made by some one else, owned by the owner (our customer)

    adding these last two checks means that our communications model is 100% efficient

    Okay so I added the code because better safe than sorry 🙂 (thanks for the code BTW, awesome, simple and very clear as usual)... but you've only (slightly) convinced me of the necessity of the first check (for owner), and not really convinced me of the need for the second check (for creator) at all.  

    Your problem with the ears seems to stem from two things that will never happen with my products, which are: 

    - multiple HUDS by different creators for the same product. The only way I could see this happening is with Gacha (and I am opposed to Gacha on moral grounds, lol)

    - HUDs that are not uniquely named.  (I would just never, ever do this)

     

    It also still seems to me that because I'm using this in the HUDs ...  

    llRegionSayTo(llGetOwner(),cmdChannel, (string)index);

    ... that a HUD can only talk to the owner of the HUD, so if the HUD is owned by someone else, it can't communicate with anyone else.  So it still seems to me that we're talking about griefers.  Someone who's essentially made a hacked (illegal) version of my HUD that can talk to other owners.

    The second situation also seems to necessitate someone making a hacked (illegal) version of the HUD and the product, and that someone who normally buys my products has unwittingly instead purchased this shady product (or more likely "found" it in a sandbox).

    Both, extreme edge cases IMO, both requiring illegality, and in both cases the intention of the griefer would be to do a lot more damage than just ripping off my few silly products.  More likely there would be some other nefarious code payload that would be the focus. 

    Anyway ... adding them anyway!, (and thanks again), but I think we're really dealing with secret agent levels of security here.  

    So here is the final, final listen code I got (for anyone following and wanting to reproduce the thing):

        listen(integer channel, string name, key id, string message) 
        {
            list crown = llGetObjectDetails(id, [OBJECT_CREATOR, OBJECT_OWNER]);
                if ((llList2Key(crown, 0) != llGetCreator()) && (llList2Key(crown, 1) != llGetOwner())) return;
    
            integer index = (integer) message;
            string  texture_key = llList2String(textures, index);
            llSetLinkPrimitiveParamsFast(2,
                [ 
                    PRIM_TEXTURE, ALL_SIDES, texture_key, <1.0, 1.0, 1.0>,ZERO_VECTOR, 0.0,
                    PRIM_NORMAL, ALL_SIDES, texture_NRM, <2.0, 2.0, 2.0>,ZERO_VECTOR, 0.0,
                    PRIM_SPECULAR, ALL_SIDES, texture_SPC, <1.0, 1.0, 1.0>,ZERO_VECTOR, 0.0,<1.0, 1.0, 1.0>, 51,0,
    
                ]);
        }

    I switched creator and owner around so it makes more sense with the variable name. 

    thanks for all the help everyone! :) 

    Sylvia


  9. 17 hours ago, Wulfie Reanimator said:

    I forgot you're already using RegionSayTo, so the "duplicate channel" issue isn't really a problem after all.

    The effort it takes to totally prevent any kind of exploit is literally one line of code that I already included in this thread. If you think it's not worth it, that's your choice. A choice I can't understand, but it's not my product so whatever.

    Well, I might add it anyway since you're being so "passively aggressive" about it, lol. :) 

    But it's literally adding yet another nesting if-else statement (the very thing I started out to avoid) just to absolutely rule out the minuscule chance that some griefer (who has read this thread BTW) hates me so much they are going to actively try to subvert my code, in order to play havoc with the textures on the 8 or 10 people who actually buy my clothes.  

    I mean, I'm a small business and I operate at a loss.  I only make the clothes so as to provide inexpensive, yet quality options for Tonic body users.  

    It's more of an Anti-Capitalist action than a business, lol.  

    Sylvia, 


  10. 49 minutes ago, Wulfie Reanimator said:

    Not quite.

    I assume the HUD name is always the same, regardless of owner? Meaning if I had the HUD, it would be called "Some HUD" and if someone else had the same HUD, it would also be called "Some HUD". If your listener is acting on all messages heard from an object called "Some HUD", it's easy for me to break all of your products.

    A channel generated directly from the owner's key is not unique nor secure.

    "0x"+(string)ID creates  a hexadecimal number with 4 bytes (8 characters, like 0x12345678).

    
    default
    {
        state_entry()
        {
            string avatar = llGetOwner();
            llOwnerSay(avatar);
            // output: "779e1d56-5500-4e22-940a-cd7b5adddbe0"
    
            string hexadecimal = "0x" + avatar;
            llOwnerSay(hexadecimal);
            // output: "0x779e1d56-5500-4e22-940a-cd7b5adddbe0"
    
            integer number = (integer)hexadecimal;
            llOwnerSay((string)number);
            // output: "2006850902" (= 0x779E1D56)
        }
    }

    Note that the first part of a UUID is 8 characters long. It's the same number.

    The first problem is that there may exist other avatars who have a key that is identical no matter which 8 characters you pick. You can't pick more characters because they'll be ignored when typecast to an integer.

    Besides that, if I create a new object and rename it to "Some HUD", I can just put my own script in there so it starts sending random messages on channels based on the avatars around me. Even if I don't know which part of the key you're using, the options are pretty limited and I can just send messages within ~200 channel range of different parts of the key.

    For these reasons, you absolutely should add an additional check to make sure that "Some HUD" is owned by the same owner.

    Hmmm ... 

    It seems like a very very very very very unlikely situation that you're talking about IMO.  

    I mean I'm going to get a completely unique number almost every time despite the outside chance that two avatars *may* generate the same number.  

    Also, we're already talking about active griefing rather than just covering off stupid mistakes, two avatars in the same room with the same product, or sloppy work on my part.  Someone would have to do a lot of work to construct something just to screw around with another avatars clothing texture HUD, and why would they?  

    Sylvia


  11. 1 hour ago, Wulfie Reanimator said:

    This does not limit the listener to objects owned by the owner. In that line of code you've created a listener that will never hear anything, because it's listening for a specific object name and a specific avatar key. By definition that's impossible to satisfy, you have to leave out the llGetOwner part and check for llGetOwnerKey separately. See:

    
    default
    {
        state_entry()
        {
            llListen(0, "Object", llGetOwner(), "");
        }
    
        listen(integer channel, string name, key id, string message)
        {
            llOwnerSay("Heard!"); // Will never happen.
        }
    }

     

    Yes, I discovered this in testing today.  

    The whole thing stopped working and since the only thing that was changed is the NULL_KEY, I went back to the old version and it worked again.  

    I think I'm just going to leave it the way it is (was) because I think having this at the top of the HUD code ...

    string  HUD_Name = "some HUD";
    integer cmdChannel;
    ...
    
    integer Key2Chan(key ID) 
    {
        return 0x80000000 | (integer)("0x"+(string)ID);
    }

    and this in the Mesh code ...

    string  HUD_Name = "some HUD";
    integer cmdChannel;
    
    integer Key2Chan(key ID) 
    {
        return 0x80000000 | (integer)("0x"+(string)ID);
    }
    
    ...
    
    default
    {
        state_entry ()
        {      
            cmdChannel = Key2Chan(llGetOwner());
            llListen(cmdChannel, HUD_Name, NULL_KEY, "");
    
    ...
    	}

    ... does essentially the same thing.  

    I'm already communicating between a named object on a secure channel that's specific to the user/owner of both objects.  The HUD even names itself on startup so it can never be called anything else.  The mesh can't listen for any other HUDs other than the named HUD, and the user would have to own both objects anyway.  No other users should even be able to listen in on the same channel.  

    I think that covers everything except ... "I've stupidly rezzed multiple copies of my own HUD all over my property and am just randomly clicking them now."  Even in that case, the result would either be the very thing the user wanted, or it just wouldn't work at all AFAICS. 

    Sylvia


  12. 6 hours ago, Mollymews said:

    i just pick up a little thing in the object script there is a listener

    
    llListen(cmdChannel, HUD_Name, NULL_KEY, "");

    narrow the listener down to the named HUD on the channel owned by the Owner

    
    llListen(cmdChannel, HUD_Name, llGetOwner(), "");

    this will prevent the object being changed by a device owned by somebody else which just happens to have the same name and is operating on the same channel

    Done

    Quote

    another little thing in the HUD script

    because we have a button named '0' then we have a issue. Any string that does not start with a number when cast to an integer will be 0 there are number of ways to resolve this. A simple way is name the buttons from 1 to 9, instead of 0 to 8, then deduct 1 and test for it

    
    touch_start(...)
    {
       integer button = (integer)llGetLinkName(llDetectedLinkNumber(0)) - 1;
       
       // any prim name that is not a number >= 1 will result in button being -1
    
       if (~button) // >= 0
       {
           ... code here same as ...
           if (button >= 6)
            
           ...
     
           llRegionSayTo ....
       }
    }

     

    and Done.  Both excellent ideas.  

    One last thing that always secretly bothered me though ... I don't "handle" the listen in the mesh object.  

    Is it really necessary for a simple thing like this?  Should I be using a timer and deleting the listen after a set time?  It seems like extra complication and also something that will get in the way of utility of the product itself.  If the HUD stops working after x seconds or whatever, the user will be left thinking it's broken.  Won't the listen just disappear by itself? 

    Sylvia


  13. Thanks again, 🙂 

    For a visually oriented person the way in which it's displayed makes all the difference.  

    For instance I looked at the key section for a long time and always saw it as:

    3 * (Text_var + Alpha_var);

    not 

    ( Text_var * 3) + Alpha_var;

    which would give: 

    3 * 0 + 0 = 0
    3 * 0 + 1 = 3
    3 * 0 + 2 = 6
    3 * 1 + 0 = 3
    3 * 1 + 1 = 6
    3 * 1 + 2 = 9
    3 * 2 + 0 = 6
    3 * 2 + 1 = 9
    3 * 2 + 2 = 12
    3 * 3 + 0 = 9
    3 * 3 + 1 = 12
    3 * 3 + 2 = 15
    3 * 4 + 0 = 12
    3 * 4 + 1 = 15
    3 * 4 + 2 = 18
    3 * 5 + 0 = 15
    3 * 5 + 1 = 18
    3 * 5 + 2 = 7

    Anyway, problem solved.  :) 

    The product will be finished in a day or two but anyone who contributed to this thread is welcome to a gift of anything in my store, although they're not likely to be of interest to all you math geeks, lol.  Check it out if you need female avatar clothing for Tonic (objectively, the BEST mesh body) or Maitreya (the most POPULAR mesh body)

    https://marketplace.secondlife.com/stores/184651 

    Sylvia


  14. 9 hours ago, Wulfie Reanimator said:

    Yes. You can imagine a list as an "array of boxes" or slots or whatever. You would have all 18 textures in a single list, all in the same order. Here's a visual (pardon my poor digital handwriting):

    529f3dba76.png

    Index 0-2 are for the first texture, each with the different kinds of sheer. Index 3-5 are for the second texture, and so on.

    Cool pic, excellent illustration of what's happening.  :)

    OK, so I took Molly's advice and put the calculations for the index in the HUD itself, which makes the code in the mesh even simpler.  Here is my finished version of both the HUD code and the Mesh code.  

     

    The only thing I can think of that may be wrong here is that I'm not "handling" the listen I guess.  

    //===== Texture Changer (HUD code) - by Sylvia Wasp ====
    
    string  HUD_Name = "some HUD";
    
    integer cmdChannel;
    integer Text_var;
    integer Alph_var;
    
    integer Key2Chan(key ID) 
    {
        return 0x80000000 | (integer)("0x"+(string)ID);
    }
    
    default
    {
        state_entry ()
        {
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_NAME,HUD_Name]);
            cmdChannel = Key2Chan(llGetOwner());
        }
    
        touch_start(integer n)
        {
            integer button = (integer)llGetLinkName(llDetectedLinkNumber(0));
    
            if (button >= 6) {
                Alph_var = button - 6;
                }   
            else {
                Text_var = button;
                } 
    
            integer index = 3 * Text_var + Alph_var;
            llRegionSayTo(llGetOwner(),cmdChannel, (string)index);
        }                
    }
    
    //===== Texture Changer (Mesh code) - by Sylvia Wasp ======
    
    string  HUD_Name = "some HUD";
    integer cmdChannel;
    
    integer Key2Chan(key ID) 
    {
        return 0x80000000 | (integer)("0x"+(string)ID);
    }
    
    key     label_tex = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    key     trans_tex = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    
    list    textures =
        [
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_01_90
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_01_80
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_01_60
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_02_90
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_02_80
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_02_60
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_03_90
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_03_80
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_03_60
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_04_90
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_04_80
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_04_60
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_05_90
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_05_80
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_05_60
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_06_90
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",    //texture_06_80
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"     //texture_06_60 
        ];
    
    default
    {
        state_entry ()
        {      
            cmdChannel = Key2Chan(llGetOwner());
            llListen(cmdChannel, HUD_Name, NULL_KEY, "");
            llSetLinkPrimitiveParamsFast(LINK_THIS,[ PRIM_TEXTURE, ALL_SIDES, trans_tex, <1.0, 1.0, 1.0>,ZERO_VECTOR, 0.0 ]);
            llSetLinkPrimitiveParamsFast(LINK_THIS,[ PRIM_TEXTURE, 0, label_tex, <-1.0, -1.0, 1.0>,ZERO_VECTOR, 0.0 ]);
            llSetLinkPrimitiveParamsFast(LINK_THIS,[ PRIM_TEXTURE, 5, label_tex, <1.0, 1.0, 1.0>,ZERO_VECTOR, 0.0 ]);
        }
    
        listen(integer channel, string name, key id, string message) 
        {
            integer index = (integer) message;
            string  texture_key = llList2String(textures, index);
            llSetLinkPrimitiveParamsFast(2,[ PRIM_TEXTURE, ALL_SIDES, texture_key, <1.0, 1.0, 1.0>,ZERO_VECTOR, 0.0 ]);
        }
    }

    This seems to work although it's late and I haven't tested it much.  

    Sokay? :) 

    Sylvia

    • Like 2

  15. 9 hours ago, Mollymews said:

    go with Wulfie's method

    making a HUD where each button is its own linked prim can be a lot simpler to visualise and get up and working

     

    edit add

    linked buttons HUD

    10 prims. 1 x backboard. 6 x texture buttons. 3 x sheer buttons

    name the texture buttons 0, 1, 2, 3, 4, 5

    name the sheer buttons 6, 7, 8

     

    Okay, thanks for this.  Here is my HUD code altered to match the idea, (I changed the variable names a bit and I had to cast the index as a string to send it)

    //===== Texture Changer (HUD) - by Sylvia Wasp ====
    
    string  HUD_Name = "some HUD";
    
    integer cmdChannel;
    integer Text_var;
    integer Alph_var;
    
    integer Key2Chan(key ID) 
    {
        return 0x80000000 | (integer)("0x"+(string)ID);
    }
    
    default
    {
        state_entry ()
        {
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_NAME,HUD_Name]);
            cmdChannel = Key2Chan(llGetOwner());
        }
    
        touch_start(integer n)
        {
            integer button = (integer)llGetLinkName(llDetectedLinkNumber(0));
    
            if (button >= 6) {
                Alph_var = button - 6;
                }   
            else {
                Text_var = button;
                } 
    
            integer index = 3 * Text_var + Alph_var;
            llRegionSayTo(llGetOwner(),cmdChannel, (string)index);
        }                
    }

    But this is what I mean about math, lol. 

    I know this bit:  integer index = 3 * Text_var + Alph_var; ... is *why* it works.  But I don't exactly understand why it works.

     I will have to think about it for a (long) while. 

    Sylvia


  16. 9 hours ago, Mollymews said:

    using the same calculation method Wulfie's shows.  Calculating a list index from some input ordered differently to the list

    when our HUD is a single surface then we can use llDetectedTouchST

    http://wiki.secondlife.com/wiki/LlDetectedTouchST


    for a HUD using this function, then in the OP minimalist case there is a 3 x 3 grid and we need a way to convert the grid reference to a list index


    in this example the texture uuids are in the HUD and we are sending the uuid to the garment/object. In another setup the UUIDs list can be in the garment/object and we send the index in the message

    Hey Molly, 🙂 

    This is pretty brilliant, but I honestly, think it's beyond me.  

    It involves math, which for me is a no-no (I'm not dumb but I'm a very visually oriented person).  It also requires me to figure out each individual HUD differently as I create them (although I guess I could create a series of HUDs with different button arrangements as templates?)  As I said to Wulfie, re-usability and solving the problem 'once and for good' is key for me.  

    TBH, I'm still trying to figure out that great solution you gave me for the listens in my avatar detector thingie, lol.  

    I keep putting the code in the wrong place which stops the whole function of the scanner.  

    Sylvia


  17. 13 hours ago, Wulfie Reanimator said:

    OH. It's super clear now, thanks for that.

    If you rename your buttons a little, you could get rid of all the if-checks and use my list method. For example:

    • Let's assign your sheer options some simple values: 0, 1, and 2.
    • Let's do the same thing for the textures: 0, 1, 2, 3, 4, and 5.
    • So the first button would be called "texture_0_" and the last one is "texture_5_"

    Based on that, you can write your HUD like this:

    The reason why we're counting from zero is because that's how list indexes work...

    (0 * 3) + 0 = index 0; First texture with 90 sheer.

    (5 * 3) + 2 = index 17; Last texture with 60 sheer. That covers all 18 textures.

    Thanks Wulfie, 

    I have to admit I don't quite get this, (because math), but if I understand generally ... you're saying that I should keep the texture keys in a list and use the information sent by the HUD to generate indexes and thus pick the correct texture from the list?  

    I usually just list the texture keys at the top of the script like this: 

    key         texture_02_80 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";    
    key         texture_02_60 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    key         texture_03_90 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";    
    key         texture_03_80 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
    key         texture_03_60 = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";    

    but putting them in an actual list makes a lot of sense.  

    Re: the HUD,

    This is the entirety of my HUD code.  It's very short and simple and allows me to re-use it over and over again.  I just change the HUD_name variable and make sure the buttons are labelled correctly.  It relies on a scheme wherein the button simply says it's name when clicked, like so: 

    //===== Texture Changer (HUD) - by Sylvia Wasp ====
    //      installed in the root prim of a linkset
    //      where the other prims are buttons labelled
    //      "button_01", "button_02", etc.
    //=================================================
    
    integer cmdChannel;
    string  HUD_Name = "some HUD";
    
    integer Key2Chan(key ID) 
    {
        return 0x80000000 | (integer)("0x"+(string)ID);
    }
    
    default
    {
        state_entry ()
        {
            llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_NAME,HUD_Name]);
            cmdChannel = Key2Chan(llGetOwner());
        }
    
        touch_start(integer n)
        {
            string button = llGetLinkName(llDetectedLinkNumber(0));
            llRegionSayTo(llGetOwner(),cmdChannel, button);
        }                
    }

    For me, this reusability is crucial as I don't have the skill to work out a new HUD for every piece of clothing.  

    So you're suggesting (for the HUD) that instead of this bit: 

        touch_start(integer n)
        {
            string button = llGetLinkName(llDetectedLinkNumber(0));
            llRegionSayTo(llGetOwner(),cmdChannel, button);
        }                

    That I detect the link number instead of the link name and send that to the clothing item instead? 

    And then use that number to find things in the list of keys based on indexes?  

    This makes a lot of sense also, but I'm not sure why I couldn't continue to use the button names, since they are logical and mostly numbers themselves (despite being technically strings of course).  

    Also, is there not a way to pick a texture (a key) based on the naming convention I've used in my list of keys?  

    I mean I can easily shorten the if-else trees that I normally use, if, instead of picking the texture key by it's full name, I can pick it though a concatenated string.  Like instead of saying (essentially) "texture_01_90" if I could say "(Text_var + Alph_variable)" instead?  

    Can I call a key just by using it's name (the name that I give it at the top of the file)?  It seems to fail when I try.   

    Sylvia

     


  18. 2 hours ago, Kardargo Adamczyk said:

    here's a snippet that should work, only two if statements

    
    list button_list = ["sheer-1","sheer-2","sheer-3","texture-4","texture-5","texture-6","texture-1","texture-2","texture-3"];
    string sheer = "sheer-1";
    string texturep = "texture-1"; //part of the texture name
    string texture;
    integer lchan = -12345; //listenchannel
    
    default
    {
        state_entry()
        {
        }
    
        touch_start(integer total_number)
        {
            llListen(lchan,"","","");
            llDialog(llDetectedKey(0),"select texture or sheer \ncurrent texture: "+texturep+"\ncurrent sheer: "+sheer,button_list,lchan);
        }
        listen(integer chan, string name, key id, string text)
        {
            if (llGetSubString(text,0,4) == "sheer")
            {
                sheer = text;
                texture = texturep+"-"+sheer;
                llOwnerSay("set texture to : "+texture);
            }
            else if (llGetSubString(text,0,6) == "texture")
            {
                texturep = text;
                texture = texturep+"-"+sheer;
                llOwnerSay("set texture to : "+texture);
            }
        }         
    }

    regs,

    Dargo

    Thanks Drago, but it's a picture HUD for changing dress textures.  llDialog is not a good fit for that situation.  

    Sylvia


  19. 3 hours ago, Wulfie Reanimator said:

    Just to recap, to make sure I've understood it correctly:

    6 textures. 3 variations of each texture.

    You want the "variant" to stay when the texture is changed. (Or just know which one to apply?)

    Either way, you want to get rid of the big if-else tree.

     

    I guess my first question is why would you need 36 if-else checks if you only have 18 textures / buttons with unique names? You should only need 18 at most.

    
    if (message == "texture_01_sheer_90")
    {
        // Do stuff;
    }
    else if (message == "texture_01_sheer_80")
    {
        // Do stuff;
    }
    else if (message == "texture_01_sheer_60")
    {
        // Do stuff;
    }
    else if (message == "texture_02_sheer_90")
    {
        // Do stuff;
    }

    Right?

    Alternatively, you could name your buttons something like "texture1", "texture2", "texture3" and so on. Then you have an ordered list in the clothing item, which uses the number as an index of that list. Then you won't need any if-checks (besides making sure you're getting correct input).

    
    list textures = ["UUID", "UUID","UUID", "UUID"];
    
    listen(integer channel, string name, key id, string message)
    {
        // 7 is the length of "texture", -1 means "end of string"
        integer index = (integer)llGetSubString(message, 7, -1);
        
        string uuid = llList2String(textures, index);
        llSetLinkTexture(LINK_SET, uuid, ALL_SIDES);
    }

     

    Well, because there are two sets of buttons and I want the choice in each set to "stick" as I said, one possible solution is to have six if-else checks for the six texture buttons with three if-else checks for the sheer buttons nested inside each one, so ... 18.  Then the three if-else checks for the sheer buttons would each have six if-else checks nested inside them for the texture buttons, which is another 18. i.e - 36.  Doing it that way, I'd have to probably add some other checks to account for conditions that are outside of what's expected too, so probably *more* than 36.  

    The thing is, if you select a texture button, the HUD has to save the level of transparency/sheer selected (one of three options) to know which level of sheer texture to apply.  The only way I can think of doing that is to have a variable that saves the level of transparency and another variable to save which of the six textures is currently selected.  Then checking for those in the giant if else structure described.  

    I think that would actually work, but it's long, kind of crazy, and I just think there has to be a better way.  

    It's a pictorial HUD, so the user selects a fabric texture based on the six pictures and then they can fool around with the level or transparency/sheer.  Because it's clothing however, I can't just adjust the alpha of the texture, I have to pre-prepare 18 detailed dress textures (3 levels of sheer for each pattern) and then pick one based on the user input from the buttons.  

    Like, if the user selects "texture_02" and then selects a different sheer factor, the HUD needs to know that "we are on texture 2 right now" and select the texture_02 version of that sheer factor.  If they then select "texture_03" instead, I need the HUD to remember that the sheer factor was 90 or 60 or whatever it happened to be and select the texture_03 version of that sheer level.  

    I'm attaching a crude mockup of the HUD (below) to illustrate.  

    Sylvia

     

    Demo_HUD.jpg

    • Thanks 1

  20. OK, I'm not a great scripter, so I'm probably going to phrase this incorrectly ... please have patience! 

    I'm a clothing designer and I make & use HUDs to change the textures on the clothes.  Up until now this has been just a simple array of 4, 6, 9 or 12 buttons, (one for each texture).  Clicking the button on the HUD makes it shout it's name ("button_01", "button_02" etc.).  The script in the clothing listens for the HUD.  It has a list of keys (UUIDs) at the top and an if, else if structure that uses llSetLinkPrimitiveParamsFast to set the textures on the correct faces and so on depending on which button it heard.

    This works fine when there's one simple array of 12 or less buttons, but I'm now trying to make a HUD with two sets of buttons, one for choosing the pattern and one for setting the level of sheerness of the pattern.  To be clear, I'm not talking about setting the Alpha of a texture, (I know how to do that) these are all still just textures but some of the textures have sheer areas.  

    There are 6 fabric patterns and 3 levels of sheerness, so ... 18 textures in all.

    For clarity, I've labelled the keys to the textures things like,  "texture_01_sheer_90", "texture_01_sheer_80", "texture_01_sheer_60", "texture_02_sheer_90" ... and so on

    But if I want the level of sheerness and the selected texture to "stick," then every time I press one of the six texture buttons, I have to test for three possible levels of sheerness' and every time I press a sheerness button I have to test for the six different patterns.  This gives me (at minimum) a super unwieldy if-else tree that has 36 levels!  It just doesn't seem like the right way to go.  

    Even if I save the pattern choice (1 of 6) and the sheerness level (1 of 3) in variables, I still have to test for that variable and I'm still stuck with the super long unwieldy if-else structure. 

    I'm sure this problem must have been solved before, can anyone point me in the right direction?  

    Assuming I've made any goddamned sense at all, lol. :) 

    Sylvia  


  21. On 1/21/2020 at 2:05 AM, hectic1 said:

    Wouldn't be much simpler to just use llKey2Name() instead of llGetDsiplayName()? It returns the legacy name of the avatar which I think it's guaranteed to consist of ascii letters only (double check on that please).

     

    Yes, except for the fact that most people don't actually use their legacy names (sadly).  

    The idea behind this scanner is that if you're in a room full of avatars and looking at the labels above their heads, what the scanner should return is what those labels say, so that the user can correlate the label on the button with the persons they see in front of them.   


  22. On 1/14/2020 at 9:44 AM, Wulfie Reanimator said:

    This has a minor problem at the cutoff point, where it will turn any multi-byte character into the either the "non-displaying" or "unrecognized" symbol.

    
    string display_name = "I, the Alpha and Omega Ω"; // 23 + 3 bytes
    llOwnerSay(display_name);
    
    string truncated = llBase64ToString(llGetSubString(llStringToBase64(display_name), 0, 31));
    llOwnerSay(truncated);
    
    Object: I, the Alpha and Omega Ω
    Object: I, the Alpha and Omega ?

    The least significant byte of Ω (which is left after truncating) is 166, which is the extended-ASCII character ¦, which isn't in my viewer font's character map so I get an error symbol (could be other symbols like ☐, ☒, �). Other characters might get cut off in a way that displays normal-looking characters that weren't actually there.

    This really only matters if you're comparing the button name directly with something, or trying to use it to find information about the avatar, because the two strings no longer match.

    That's a neat way of getting around the problem though.

    thanks for this detail Wulfie. 🙂 

    Overall, though I don't see this as a problem, especially when the alternative is severely truncated names.  The scanner is mostly for use at dances, shopping malls, etc. and let's face it, most avatars won't be using characters that cause any problems. 

    The majority of avatars just use regular names in the language symbols of their home country in standard fonts available on most modern computers.  Only a small sub-set of avatars will use "weird/interesting" characters from other languages and font sets (for the "cool" factor 🙂 ), and an even smaller subset of those will use characters that might cause a problem with the scanner.  

    In testing, it seems that llBase64ToString deals with those rare cases very well.  

    All the names I've seen on the buttons are clear and easily recognisable as the folks standing around me when I'm scanning. 


  23. 12 minutes ago, Chic Aeon said:

    No answer. They appear to get corrupted in the database. They can sometimes be FINE on an object still but the texture itself is no longer good. Always good to keep copies of ALL your textures on your computer  --- and of course a backup of the files also.  

     

    Also, like other assets, textures can mysteriously disappear from the complete database (not just your inventory). So sending important ones to an alt doesn't help :D.   

    thanks Chic, I was worried that was the answer, but thanks anyway :) 

    Seems to happen way more often with TGA's too for what it's worth.


  24. I've seen this happen on and off over the years and never heard of a good explanation, so here goes ...  

    Basically, pictures (textures) that I've uploaded into inventory, (especially those I use in my profile), just randomly sometimes show up as blurred.  They never resolve into an image.  I've tried rebooting, changing graphics settings and all the typical things, but it isn't that.  I have a good computer, I run on mostly Max settings etc.  It's as if the server is just storing a low-res version and has dispensed with the actual file.  

    This is NOT a transient problem.  Once a texture gets blurred out, there seems no fixing for it.  It never "comes back."  I can download this textures out of SL and they show up as blurred on my desktop.

    It seems SL is just randomly scr*wing up my textures and no one seems to know why or how or what to do about it.  

×
×
  • Create New...