Table of Contents

About

This item is a customizable banner with texture change support and with a matching holding animation.

Adding Textures

The only requirements to change the textures is to drag and drop textures into the root primitive of the banner.

Animation

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.        //
///////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
integer wasMenuIndex = 0;
list wasDialogMenu(list input, list actions, string direction) {
    integer cut = 11-wasListCountExclude(actions, [""]);
    if(direction == ">" &&  (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) {
        ++wasMenuIndex;
        jump slice;
    }
    if(direction == "<" && wasMenuIndex-1 >= 0) {
        --wasMenuIndex;
        jump slice;
    }
@slice;
    integer multiple = wasMenuIndex*cut;
    input = llList2List(input, multiple+wasMenuIndex, multiple+cut+wasMenuIndex);
    input = wasListMerge(input, actions, "");
    return input;
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
integer wasListCountExclude(list input, list exclude) {
    if(llGetListLength(input) == 0) return 0;
    if(llListFindList(exclude, (list)llList2String(input, 0)) == -1)
        return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
    return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
list wasListMerge(list l, list m, string merge) {
    if(llGetListLength(l) == 0 && llGetListLength(m) == 0) return [];
    string a = llList2String(m, 0);
    if(a != merge) return [ a ] + wasListMerge(l, llDeleteSubList(m, 0, 0), merge);
    return [ llList2String(l, 0) ] + wasListMerge(llDeleteSubList(l, 0, 0), llDeleteSubList(m, 0, 0), merge);
}
 
list textures = [];
integer chan = 0;
integer listenId = 0;
 
default {
    state_entry() {
        integer i = llGetInventoryNumber(INVENTORY_TEXTURE) - 1;
        do {
            textures += llGetInventoryName(INVENTORY_TEXTURE, i);
        } while (--i > -1);
        state select;
    }
    changed(integer change) {
        llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state select {
    state_entry() {
        chan = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
    }
    touch_start(integer num) {
        // Lock to owner.
        if(llDetectedKey(0) != llGetOwner()) {
            return;
        }
        listenId = llListen(
            chan,
            "",
            llGetOwner(),
        "");
        llDialog(
            llGetOwner(),
            "Please choose the texture: ",
            wasDialogMenu(textures, ["⟵ Back", "", "Next ⟶"], ""),
            chan
        );
    }
    listen(integer channel, string name, key id, string message) {
        if(message == "⟵ Back") {
            llDialog(
                id,
                "Please choose the texture: ",
                wasDialogMenu(textures, ["⟵ Back", "", "Next ⟶"], "<"),
                chan
            );
            return;
        }
        if(message == "Next ⟶") {
            llDialog(id,
                "Please choose the texture: ",
                wasDialogMenu(textures, ["⟵ Back", "", "Next ⟶"], ">"),
                chan
            );
            return;
        }
        integer i = llListFindList(
            textures,
            [
                message
            ]
        );
 
        string texture = llList2String(textures, i);
 
        llSetLinkPrimitiveParamsFast(3, [PRIM_TEXTURE, ALL_SIDES, texture, <-1, 1, 0>, <0, 0, 0>, PI_BY_TWO ]);
        llSetLinkPrimitiveParamsFast(5, [PRIM_TEXTURE, ALL_SIDES, texture, <-1, 1, 0>, <0, 0, 0>, PI_BY_TWO ]);
        llListenRemove(listenId);
    }
    changed(integer change) {
        llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
}