About

This item is a colorable balloon with a built-in resizer and additionally fully animated to be compatible with animation overriders.

Code

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2021 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
 
float MAXIMUM_PRIMITIVE_SIZE =  64;
float MINIMUM_PRIMITIVE_SIZE = .01;
 
integer channel = 0;
key toucher = NULL_KEY;
list scale_menu = ["-.05", "-.10", "-.25", "+.05", "+.10", "+.25", "[✖︎] SECURE", "[ + ]", "[ - ]", "⏏ Exit" ];
float scale = 1;
 
default {
    state_entry() {
        if(toucher == NULL_KEY) {
            return;
        }
        channel = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "Please pick from the menu", ["⎙ Color", "⎙ Size", "⏏ Exit"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) {
            return;
        }
        toucher = llDetectedKey(0);
        llListen(channel, "", toucher, "");
        llDialog(toucher, "Please pick from the menu", ["⎙ Color", "⎙ Size", "⏏ Exit"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") {
            llResetScript();
        }
        if(message == "⎙ Color") {
            state color;
        }
        if(message == "⎙ Size") {
            state rescale;
        }
        llDialog(toucher, "Please pick from the menu", ["⎙ Color", "⎙ Size", "⏏ Exit"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state rescale {
    state_entry() {
        if(toucher == NULL_KEY) {
            return;
        }
        llListen(channel, "", toucher, "");
        llDialog(toucher, "Rescale the item: ", scale_menu, channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) {
            return;
        }
        llListen(channel, "", toucher, "");
        llDialog(toucher, "Rescale the item: ", scale_menu, channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") {
            state default;
        }
        if(message == "[✔] SECURE") {
            scale_menu = llListReplaceList(scale_menu, [ "[✖︎] SECURE" ], 6, 6);
            jump menu;
        }
        if(message == "[✖︎] SECURE") {
            scale_menu = llListReplaceList(scale_menu, [ "[✔] SECURE" ], 6, 6);
            jump menu;
        }
        if(message == "[ + ]" || message == "[ - ]") {
            // Check primitive limitations before chaning the ratio.
            float mod = (float)(
                llGetSubString(
                    message, 
                    2, 
                    2
                ) + (string).01
            );
            integer i = 5;
            do {
                if(llFabs(llList2Float(scale_menu, i)) + mod < MINIMUM_PRIMITIVE_SIZE ||
                    llFabs(llList2Float(scale_menu, i)) + mod > MAXIMUM_PRIMITIVE_SIZE) {
                    jump menu;
                }
            } while(--i>-1);
            i = 5;
            do {
                string scaler = llGetSubString(
                    llList2String(
                        scale_menu, 
                        i
                    ), 
                    0, 
                    0
                );
                string modify = llGetSubString(
                    (string)(
                        llFabs(
                            llList2Float(
                                scale_menu, 
                                i
                            )
                        ) + mod
                    ), 
                    0, 
                    3
                );
                scale_menu = llListReplaceList(
                    scale_menu, 
                    (list)(scaler + modify), 
                    i, 
                    i
                );
            } while(--i>-1);
            jump menu;
        }
        if((float)message) {
            scale += (float)message;
            state perform_rescale;
        }
@menu;
        llDialog(toucher, "Rescale the item: ", scale_menu, channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state perform_rescale {
    state_entry() {
        integer i;
        if(llList2String(scale_menu, 6) == "[✔] SECURE") {
            i = llGetNumberOfPrims();
            vector dim;
            do {
                if(i != 1) {
                    dim = scale * llList2Vector(
                        llGetLinkPrimitiveParams(
                            i, 
                            [
                                PRIM_SIZE
                            ]
                        ), 
                        0
                    );
                    jump secure_check;
                }
                dim = scale * llGetScale();
@secure_check;
                // If the resize should be performed securely, any primitive that would
                // have a size smaller than .01 or 64 on all axes will deform the object.
                if(dim.x < MINIMUM_PRIMITIVE_SIZE ||
                    dim.y < MINIMUM_PRIMITIVE_SIZE ||
                    dim.z < MINIMUM_PRIMITIVE_SIZE ||
                    dim.x > MAXIMUM_PRIMITIVE_SIZE ||
                    dim.y > MAXIMUM_PRIMITIVE_SIZE ||
                    dim.z > MAXIMUM_PRIMITIVE_SIZE) jump exit;
            } while(--i>0);
        }
        i = llGetNumberOfPrims();
        do {
            list data = llGetLinkPrimitiveParams(
                i, 
                [
                    PRIM_SIZE,
                    PRIM_POS_LOCAL
                ]
            );
            llSetLinkPrimitiveParamsFast(i,
                [
                    PRIM_SIZE, scale * llList2Vector(data, 0),
                    PRIM_POSITION, scale * llList2Vector(data, 1)
                ]
            );
        } while(--i>1);
        llSetScale(scale * llGetScale());
@exit;
        scale = 1;
        state rescale;
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state color {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "Please use the buttons to change the color: ", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) {
            return;
        }
        llListen(channel, "", toucher, "");
        llDialog(toucher, "Please use the buttons to change the color: ", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") {
            state default;
        }
        list params = llGetLinkPrimitiveParams(1, [PRIM_COLOR, ALL_SIDES]);
        vector color = llList2Vector(params, 0);
        float alpha = llList2Float(params, 1);
        if(message == "R ▼") {
            llSetLinkPrimitiveParamsFast(
                1, 
                [
                    PRIM_COLOR, 
                    ALL_SIDES, 
                    color - <.1,0,0>, 
                    alpha
                ]
            );
            jump menu;
        }
        if(message == "R ▲") {
            llSetLinkPrimitiveParamsFast(
                1, 
                [
                    PRIM_COLOR, 
                    ALL_SIDES, 
                    color + <.1,0,0>, 
                    alpha
                ]
            );
            jump menu;
        }
        if(message == "G ▼") {
            llSetLinkPrimitiveParamsFast(
                1, 
                [
                    PRIM_COLOR, 
                    ALL_SIDES, 
                    color - <0,.1,0>, 
                    alpha
                ]
            );
            jump menu;
        }
        if(message == "G ▲") {
            llSetLinkPrimitiveParamsFast(
                1, 
                [
                    PRIM_COLOR, 
                    ALL_SIDES, 
                    color + <0,.1,0>, 
                    alpha
                ]
            );
            jump menu;
        }
        if(message == "B ▼") {
            llSetLinkPrimitiveParamsFast(
                1, 
                [
                    PRIM_COLOR, 
                    ALL_SIDES, 
                    color - <0,0,.1>, 
                    alpha
                ]
            );
            jump menu;
        }
        if(message == "B ▲") {
            llSetLinkPrimitiveParamsFast(
                1, 
                [
                    PRIM_COLOR, 
                    ALL_SIDES, 
                    color + <0,0,.1>, 
                    alpha
                ]
            );
            jump menu;
        }
@menu;
        llDialog(toucher, "Please use the buttons to change the color: ", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}