Difference between revisions of "User:Pazako Karu/LinksetResizerWithMenu"

From Second Life Wiki
Jump to navigation Jump to search
 
Line 1: Line 1:
This script resizes a linkset in X,Y,Z as desired without any configuration.
This script resizes a linkset in X,Y,Z as desired without any configuration.<br/>
 
On adding the script, it asks for a limit in case you don't want the true max.<br/>
On adding the script, it asks for a limit in case you don't want the true max.
I added this since the 'true max' of a small item would be hilariously large.<br/>
 
I added this since the 'true max' of a small item would be hilariously large.
 
'' Its not rocket surgery ''


= Code =
= Code =
<source lang="lsl2">
<syntaxhighlight lang="lsl2">
// Linkset Resizer with Menu
// Linkset Resizer with Menu
// by: Pazako Karu
// by: Pazako Karu
Line 113: Line 109:
{
{
     if (input > max_scale) return max_scale;
     if (input > max_scale) return max_scale;
// If you want to scale an object and ignore minimums, just comment out the next line
     if (input < min_scale) return min_scale;
     if (input < min_scale) return min_scale;
     return input;
     return input;
Line 206: Line 203:
     }
     }
}
}
</source>
</syntaxhighlight>


= License =
= License =
You may use, abuse, and distribute this object in any way, other than simply repacking for sale.
You may use, abuse, and distribute this script in any way, other than simply repacking for sale.<br/>
You may include this object as part of a sellable object in any form, including full permission.
You may include this as part of a sellable object in any form, including full permission.<br/>
This was made using some firestorm preprocessing commands and is not given with any promise of readability or assistance with modification.
This was made using some firestorm preprocessing commands and is not given with any promise of readability or assistance with modification.<br/>
'' Its not rocket surgery ''

Latest revision as of 15:25, 14 September 2024

This script resizes a linkset in X,Y,Z as desired without any configuration.
On adding the script, it asks for a limit in case you don't want the true max.
I added this since the 'true max' of a small item would be hilariously large.

Code

// Linkset Resizer with Menu
// by: Pazako Karu
// This script resizes a linkset in X,Y,Z as desired without any configuration

float max_scale;
float min_scale;
vector scale = <1,1,1>;

list link_scales = [];
list link_positions = [];
integer X = TRUE;
integer Y = TRUE;
integer Z = TRUE;
integer SCANNED = FALSE;

//#include "dialog.lsl"
list DIALOG_DATA;

setDialog(key id, string caption, list buttons, integer context) 
{   getDialog(id); 
    if (llList2Integer(DIALOG_DATA, -4) > llGetTime())  
        cleanDialogs();
    else while (llGetListLength(DIALOG_DATA) >= 40)     
    {   llListenRemove(llList2Integer(DIALOG_DATA,2));        
        DIALOG_DATA = llList2List(DIALOG_DATA, 4, -1);  
    }
    integer channel = -(integer)llFrand(DEBUG_CHANNEL);
    DIALOG_DATA += [llGetTime()+60, id, llListen(channel, llKey2Name(id), id, ""), context]; 
    llDialog(id, caption, buttons, channel);
}

integer getDialog(key id)
{   integer index = llListFindList(DIALOG_DATA, [id]); 
    integer context = llList2Integer(DIALOG_DATA,index+2); 
    if (~index) 
    {   llListenRemove(llList2Integer(DIALOG_DATA, index+1)); 
        DIALOG_DATA = llDeleteSubList(DIALOG_DATA, index-1, index+2); 
    }
    else context = 0; 
    return context; 
}

cleanDialogs()
{   
    integer index; 
    for (index = 2; index < llGetListLength(DIALOG_DATA); index+=4)
        llListenRemove(llList2Integer(DIALOG_DATA,index));
    DIALOG_DATA=[];
}

makeMenu()
{
    list options = ["-1%","-5%","-10%","+1%","+5%","+10%"];
    if (X) options += ["[X]"]; else options += ["X"];
    if (Y) options += ["[Y]"]; else options += ["Y"];
    if (Z) options += ["[Z]"]; else options += ["Z"];
    options += ["Max", "Min", "More..."];
    setDialog(llGetOwner(), (string)[ "Max scale: ", max_scale, "\nMin scale: ", min_scale, "\n\nCurrent scale: ", scale], options, 1);
    llSetTimerEvent(120);
}

scanLinkset()
{
    integer links = llGetNumberOfPrims();
    integer link;
    integer offset = (links != 1); // add 1 if more than one prim (as linksets start numbering with 1)
    list params;

    for (link = 0; link < links; ++link)
    {
        params = llGetLinkPrimitiveParams(link + offset, [PRIM_POS_LOCAL, PRIM_SIZE]);
        link_positions += llList2Vector(params, 0);
        link_scales    += llList2Vector(params, 1);
    }
    if (max_scale == 0)
        max_scale = llGetMaxScaleFactor() * 0.999999;
    min_scale = llGetMinScaleFactor() * 1.000001;
    SCANNED = TRUE;
    llOwnerSay("Ready to use! Max scale set to " + (string)max_scale + "m");
}
resizeObject(vector scale)
{
    integer links = llGetNumberOfPrims();
    integer link;
    integer offset = (links != 1);
    
    // scale the root
    llSetLinkPrimitiveParamsFast(offset, [PRIM_SIZE, notDot(scale,llList2Vector(link_scales, 0))]);
    
    // scale all but the root
    for (link = 1; link < links; link++)
    {
        llSetLinkPrimitiveParamsFast(link + offset,
            [PRIM_SIZE,      notDot(scale, llList2Vector(link_scales,    link)),
             PRIM_POS_LOCAL, notDot(scale, llList2Vector(link_positions, link))]);
    }
}
vector notDot(vector A, vector B)
{
    return <A.x*B.x, A.y*B.y, A.z*B.z>;
}
float limit(float input)
{
    if (input > max_scale) return max_scale;
// If you want to scale an object and ignore minimums, just comment out the next line
    if (input < min_scale) return min_scale;
    return input;
}
default
{
    state_entry()
    {
        setDialog(llGetOwner(), "Please define max scale, or leave blank to allow actual maximum, which may be very very large.", ["!!llTextBox!!"], 4);
    }
    touch_start(integer total)
    {
        if (llDetectedKey(0) == llGetOwner())
        {
            if (SCANNED == TRUE)
                makeMenu();
            else llResetScript();
        }
    }
    timer()
    {
        cleanDialogs();
        llSetTimerEvent(0);
    }
    listen(integer channel, string name, key id, string msg)
    {
        integer CONTEXT = getDialog(id);
        if (CONTEXT == 4)
        {
            max_scale = llFabs((float)msg);
            if (max_scale > llGetMaxScaleFactor() * 0.999999)
                max_scale = llGetMaxScaleFactor() * 0.999999;
            scanLinkset();
        }
        else if (SCANNED == TRUE)
        {
            if (CONTEXT == 1)
            {
                     if (msg == "[X]") X = FALSE;
                else if (msg == "[Y]") Y = FALSE;
                else if (msg == "[Z]") Z = FALSE;
                else if (msg ==  "X")  X = TRUE;
                else if (msg ==  "Y")  Y = TRUE;
                else if (msg ==  "Z")  Z = TRUE;
                else if (msg == "Max")      scale = max_scale * <1,1,1>;
                else if (msg == "Min")      scale = min_scale * <1,1,1>;
                else if (msg == "More...")  setDialog(id, "\nBonus options:", ["Delete", "Restore", "Back"], CONTEXT=2);
                else // Number chosen
                {
                    float factor = (float)msg/100;
                    if (factor > 0)
                    {
                        factor += 1; // 1.05
                        if (X) scale = notDot(scale, <factor,1,1>);
                        if (Y) scale = notDot(scale, <1,factor,1>);
                        if (Z) scale = notDot(scale, <1,1,factor>);
                    }
                    else
                    {
                        factor = 1/(1-factor);
                        if (X) scale = notDot(scale, <factor,1,1>);
                        if (Y) scale = notDot(scale, <1,factor,1>);
                        if (Z) scale = notDot(scale, <1,1,factor>);
                    }
                }
                // Limit scale to bounds
                scale = <limit(scale.x), limit(scale.y), limit(scale.z)>;
                
                resizeObject(scale);
                if (CONTEXT == 1)
                    makeMenu();
            }
            else if (CONTEXT == 2) // Bonus options
            { //"Delete", "Defaults", "Back"
                     if (msg == "Back") makeMenu();
                else if (msg == "Delete") setDialog(id, "\nAre you sure you want to delete the resizer script?", ["Yes", "No"], 3);
                else if (msg == "Restore")
                {
                    scale = <1,1,1>;
                    resizeObject(scale);
                    makeMenu();
                }
            }
            else if (CONTEXT == 3) // Delete confirm
            {
                if (msg == "Yes")
                {
                    llRegionSayTo(id, 0, "Script deleted");
                    llRemoveInventory(llGetScriptName());
                }
            }
        }
    }
}

License

You may use, abuse, and distribute this script in any way, other than simply repacking for sale.
You may include this as part of a sellable object in any form, including full permission.
This was made using some firestorm preprocessing commands and is not given with any promise of readability or assistance with modification.
Its not rocket surgery