Table of Contents

Reference

Scripts

The foil contains:

Animation

The animation script is responsible for triggering the Extend pose.

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2022 - 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) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if(llStringLength(data) == 0) return "";
    if(llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
    if(i != -1) return llList2String(a, 2*i+1);
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if(llStringLength(k) == 0) return "";
    if(llStringLength(v) == 0) return "";
    if(llStringLength(data) == 0) return k + "=" + v;
    integer i = llListFindList(
        llList2ListStrided(
            llParseString2List(data, ["&", "="], []),
            0, -1, 2
        ),
    [ k ]);
    if(i != -1) return llDumpList2String(
        llListReplaceList(
            llParseString2List(data, ["&"], []),
            [ k + "=" + v ],
        i, i),
    "&");
    return data + "&" + k + "=" + v;
}
 
integer share;
integer csh;
string identify = "c148cf4";
 
key owner;
 
default {
    state_entry() {
        owner = llGetOwner();
        share = (integer)("0x8" + identify);
 
        state on;
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            return;
        }
    }
}
 
state on {
    state_entry() {
        if(owner == NULL_KEY && llGetAttached() == 0) {
            return;
        }
 
        llRequestPermissions(
            owner, 
            PERMISSION_TRIGGER_ANIMATION
        );
    }
    listen(integer channel, string name, key id, string message) {
        key object = llList2Key(
            llGetObjectDetails(
                id, 
                [ 
                    OBJECT_OWNER 
                ]
            ),
            0
        );
 
        if(object == owner) {
            string status = wasKeyValueGet(
                "status", 
                message
            );
 
            if(status == "off") {
                state off;
            }
        }
    }
    run_time_permissions(integer perm) {
        if(perm & PERMISSION_TRIGGER_ANIMATION) {
            llStartAnimation("Extend");
 
            csh = llListen(
                share, 
                "", 
                "", 
                ""
            );
            return;
        }
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            llRequestPermissions(
                owner, 
                PERMISSION_TRIGGER_ANIMATION
            );
            return;
        }
    }
    state_exit() {
        llListenRemove(csh);
    }
}
 
state off {
    state_entry() {  
        if(owner == NULL_KEY && llGetAttached() == 0) {
            return;
        }
 
        llRequestPermissions(
            owner, 
            PERMISSION_TRIGGER_ANIMATION
        );
    }
    listen(integer channel, string name, key id, string message) {
        key object = llList2Key(
            llGetObjectDetails(
                id, 
                [ 
                    OBJECT_OWNER 
                ]
            ),
            0
        );
 
        if(object == owner) {
            string status = wasKeyValueGet(
                "status", 
                message
            );
 
            if(status == "on") {
                state on;
            }
        }
    }
    run_time_permissions(integer perm) {
        if(perm & PERMISSION_TRIGGER_ANIMATION) {
            llStopAnimation("Extend");
 
            csh = llListen(
                share, 
                "", 
                "", 
                ""
            );
        }
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            llRequestPermissions(
                owner, 
                PERMISSION_TRIGGER_ANIMATION
            );
            return;
        }
    }
    state_exit() {
        llListenRemove(csh);
    }
}

The extend pose is available here:

Program

The program script is used for drawing in mouse look.

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2022 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////
// Derived from: [Fox Labs] Sky Writer                                   //
///////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if(llStringLength(data) == 0) return "";
    if(llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
    if(i != -1) return llList2String(a, 2*i+1);
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if(llStringLength(k) == 0) return "";
    if(llStringLength(v) == 0) return "";
    if(llStringLength(data) == 0) return k + "=" + v;
    integer i = llListFindList(
        llList2ListStrided(
            llParseString2List(data, ["&", "="], []),
            0, -1, 2
        ),
    [ k ]);
    if(i != -1) return llDumpList2String(
        llListReplaceList(
            llParseString2List(data, ["&"], []),
            [ k + "=" + v ],
        i, i),
    "&");
    return data + "&" + k + "=" + v;
}
 
vector size;
vector last;
float distance = 5.0;
integer rezzers;
string exception;
 
integer share;
integer csh;
string identify = "c148cf4";
 
integer channel;
key owner;
 
integer waggle;
 
default {
    state_entry() {
        llSetText("", <1,1,1>, 1.0);
        llParticleSystem([]);
 
        if(llGetAttached() == 0) {
            exception = "Item not attached.";
            state fault;
        }
 
        owner = llGetOwner();
        share = (integer)("0x8" + identify);
        size = llGetAgentSize(owner);
        channel = (integer)("0x8" + llGetSubString(llGetKey(), 0, 6));
 
        state on;
    }
    attach(key id) {
        llResetScript();
    }
}
 
state on {
    state_entry() {
        if(owner == NULL_KEY && llGetAttached() == 0) {
            exception = "Item not attached.";
            state fault;
        }
 
        llRequestPermissions(
            owner,
            PERMISSION_TAKE_CONTROLS
        );
    }
    listen(integer channel, string name, key id, string message) {
        key object = llList2Key(
            llGetObjectDetails(
                id, 
                [ 
                    OBJECT_OWNER 
                ]
            ),
            0
        );
 
        if(object == owner) {
            string status = wasKeyValueGet(
                "status", 
                message
            );
 
            if(status == "off") {
                state off;
            }
        }
    }
    run_time_permissions(integer perms) {
        if (perms & PERMISSION_TAKE_CONTROLS) {
            llTakeControls(
                CONTROL_ML_LBUTTON, 
                TRUE, 
                TRUE
             );
 
            string data = "";
            data = wasKeyValueSet(
                "status", 
                "on",
                data
            );
            llRegionSay(
                share, 
                data
            );
 
            csh = llListen(
                share, 
                "", 
                "", 
                ""
            );
        }
    }
    link_message(integer sender, integer num, string message, key id) {
        string link = wasKeyValueGet(
            "waggle",
            message
        );
 
        if(link != "") {
            waggle = (integer)link;
 
            llMessageLinked(
                waggle, 
                0, 
                "", 
                NULL_KEY
            );
        }
    }
    control(key id, integer level, integer edge) {
        // mouse down
        if(CONTROL_ML_LBUTTON & level && edge != 0) {
            llMessageLinked(
                waggle, 
                0, 
                "", 
                NULL_KEY
            );
 
            llSetTimerEvent(.01);
            return;
        }
 
        // mouse hold
        if(CONTROL_ML_LBUTTON & level) {
            llMessageLinked(
                waggle, 
                0, 
                "", 
                NULL_KEY
            );
 
            vector position = <0, 0 , size.z / 2.0> + llGetPos() + 
                distance * llRot2Fwd(llGetRot());
 
            string data = "";
            data = wasKeyValueSet(
                "position", 
                (string)position, 
                data
            );
            data = wasKeyValueSet(
                "param", 
                (string)channel, 
                data
            );
 
            llMessageLinked(
                LINK_THIS,
                rezzers,
                data,
                NULL_KEY
            );
 
            rezzers = ++rezzers % 10;
            last = position;
 
            return;
        }
 
        // mouse up
        llSetTimerEvent(0);
    }
    timer() {
        llRegionSay(channel, ".");
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
 
            llRequestPermissions(
                owner,
                PERMISSION_TAKE_CONTROLS
            );
            return;
        }
    }
    state_exit() {
        llListenRemove(csh);
    }
}
 
state off {
    state_entry() {
        if(owner == NULL_KEY && llGetAttached() == 0) {
            exception = "Item not attached.";
            state fault;
        }
 
        llRequestPermissions(
            owner, 
            PERMISSION_TAKE_CONTROLS
        );
    }
    run_time_permissions(integer perm) {
        if(perm & PERMISSION_TAKE_CONTROLS) {
            llReleaseControls();
 
            string data = "";
            data = wasKeyValueSet(
                "status", 
                "off",
                data
            );
            llRegionSay(
                share, 
                data
            );
 
            csh = llListen(
                share, 
                "", 
                "", 
                ""
            );
 
            return;
        }
    }
    listen(integer channel, string name, key id, string message) {
        key object = llList2Key(
            llGetObjectDetails(
                id, 
                [ 
                    OBJECT_OWNER 
                ]
            ),
            0
        );
 
        if(object == owner) {
            string status = wasKeyValueGet(
                "status", 
                message
            );
 
            if(status == "on") {
                state on;
            }
        }
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            return;
        }
    }
    state_exit() {
        llListenRemove(csh);
    }
}
 
state fault {
    state_entry() {
        llSetText(exception, <1,1,1>, 1.0);
        llParticleSystem(
            [
                PSYS_SRC_TEXTURE, llGetInventoryName(INVENTORY_TEXTURE, 0),
                PSYS_PART_START_SCALE,<0.8, 1.6, 0>,
                PSYS_PART_END_SCALE,<0.8, 1.6, 0>,
                PSYS_PART_START_COLOR,<1, 1, 1>,
                PSYS_PART_END_COLOR,<1,1,1>,
                PSYS_PART_START_ALPHA,1,
                PSYS_PART_END_ALPHA, 1,
                PSYS_SRC_BURST_PART_COUNT, 1,
                13, 0.5,
                PSYS_PART_MAX_AGE,.3,
                PSYS_SRC_MAX_AGE, 0.0,
                PSYS_SRC_PATTERN, 4,
                PSYS_SRC_BURST_SPEED_MIN, 0.0,
                18, 0.0,
                22, 0.03*3.141593,
                PSYS_SRC_ANGLE_END, 0*3.141593,
                8,<0.0,0.0,0>,
                0,(0|1|PSYS_PART_EMISSIVE_MASK)
            ]
        );
    }
    attach(key id) {
        llResetScript();
    }
    on_rez(integer num) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
}

Reveal

The reveal script will hide or unhide the foil whenever the helm is activated or deactivated.

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2022 - 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) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if(llStringLength(data) == 0) return "";
    if(llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
    if(i != -1) return llList2String(a, 2*i+1);
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if(llStringLength(k) == 0) return "";
    if(llStringLength(v) == 0) return "";
    if(llStringLength(data) == 0) return k + "=" + v;
    integer i = llListFindList(
        llList2ListStrided(
            llParseString2List(data, ["&", "="], []),
            0, -1, 2
        ),
    [ k ]);
    if(i != -1) return llDumpList2String(
        llListReplaceList(
            llParseString2List(data, ["&"], []),
            [ k + "=" + v ],
        i, i),
    "&");
    return data + "&" + k + "=" + v;
}
 
integer share;
integer csh;
string identify = "c148cf4";
 
key owner;
 
default {
    state_entry() {
        share = (integer)("0x8" + identify);
        owner = llGetOwner();
        state on;
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            return;
        }
    }
}
 
state on {
    state_entry() {
        llSetLinkAlpha(
            LINK_SET, 
            1.0, 
            ALL_SIDES
        );
 
        csh = llListen(
            share, 
            "", 
            "", 
            ""
        );
    }
    listen(integer channel, string name, key id, string message) {
        key object = llList2Key(
            llGetObjectDetails(
                id, 
                [ 
                    OBJECT_OWNER 
                ]
            ),
            0
        );
 
        if(object == owner) {
            string status = wasKeyValueGet(
                "status", 
                message
            );
 
            if(status == "off") {
                state off;
            }
        }
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            return;
        }
    }
    state_exit() {
        llListenRemove(csh);
    }
}
 
state off {
    state_entry() {
        llSetLinkAlpha(
            LINK_SET, 
            0.0, 
            ALL_SIDES
        );
 
        csh = llListen(
            share, 
            "", 
            "", 
            ""
        );
    }
    listen(integer channel, string name, key id, string message) {
        key object = llList2Key(
            llGetObjectDetails(
                id, 
                [ 
                    OBJECT_OWNER 
                ]
            ),
            0
        );
 
        if(object == owner) {
            string status = wasKeyValueGet(
                "status", 
                message
            );
 
            if(status == "on") {
                state on;
            }
        }
    }
    attach(key id) {
        if(id != NULL_KEY && llGetAttached() != 0) {
            owner = id;
            return;
        }
    }
    state_exit() {
        llListenRemove(csh);
    }
}

Waggle

The waggle script will make the blade tilt from side to side when the avatar wearing the helm and the foil is in mouse look and drawing patterns.

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2022 - 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) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if(llStringLength(data) == 0) return "";
    if(llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
    if(i != -1) return llList2String(a, 2*i+1);
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if(llStringLength(k) == 0) return "";
    if(llStringLength(v) == 0) return "";
    if(llStringLength(data) == 0) return k + "=" + v;
    integer i = llListFindList(
        llList2ListStrided(
            llParseString2List(data, ["&", "="], []),
            0, -1, 2
        ),
    [ k ]);
    if(i != -1) return llDumpList2String(
        llListReplaceList(
            llParseString2List(data, ["&"], []),
            [ k + "=" + v ],
        i, i),
    "&");
    return data + "&" + k + "=" + v;
}
 
default {
    state_entry() {
        llSetTimerEvent(1);
    }
    link_message(integer sender, integer num, string message, key id) {
        state wait;
    }
    timer() {
        string data = "";
        data = wasKeyValueSet(
            "waggle", 
            (string)llGetLinkNumber(),
            data
        );
        llMessageLinked(
            LINK_SET, 
            0, 
            data, 
            NULL_KEY
        );
    }
    attach(key id) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
    state_exit() {
        llSetTimerEvent(0);
    }
}
 
state wait {
    state_entry() {
        llSetLinkPrimitiveParamsFast(
            LINK_THIS,
            [
                PRIM_FLEXIBLE, TRUE,
                0,
                1,
                0,
                0,
                10,
                ZERO_VECTOR
            ]
        );
    }
    link_message(integer sender, integer num, string message, key id) {
        state a;
    }
    attach(key id) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
}
 
state a {
    state_entry() {
        llSetLinkPrimitiveParamsFast(
            LINK_THIS,
            [
                PRIM_FLEXIBLE, TRUE,
                0,
                1,
                0,
                0,
                10,
                <-1, 0, 0>
            ]
        );
 
        llSetTimerEvent(1);
    }
    link_message(integer sender, integer num, string message, key id) {
        state b;
    }
    timer() {
        state wait;
    }
    attach(key id) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
    state_exit() {
        llSetTimerEvent(0);
    }
}
 
state b {
    state_entry() {
        llSetLinkPrimitiveParamsFast(
            LINK_THIS,
            [
                PRIM_FLEXIBLE, TRUE,
                0,
                1,
                0,
                0,
                10,
                <1, 0, 0>
            ]
        );
 
        llSetTimerEvent(1);
    }
    link_message(integer sender, integer num, string message, key id) {
        state a;
    }
    timer() {
        state wait;
    }
    attach(key id) {
        llResetScript();
    }
    changed(integer change) {
        llResetScript();
    }
    state_exit() {
        llSetTimerEvent(0);
    }
}

Rezzer Scripts (0 to 9)

The foil contains 10 identical scripts named 0 to 9 with the following contents that are responsible for rezzing the orb primitive inside the foil:

///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2022 - 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) 2015 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if(llStringLength(data) == 0) return "";
    if(llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]);
    if(i != -1) return llList2String(a, 2*i+1);
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: CC BY 2.0    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if(llStringLength(k) == 0) return "";
    if(llStringLength(v) == 0) return "";
    if(llStringLength(data) == 0) return k + "=" + v;
    integer i = llListFindList(
        llList2ListStrided(
            llParseString2List(data, ["&", "="], []),
            0, -1, 2
        ),
    [ k ]);
    if(i != -1) return llDumpList2String(
        llListReplaceList(
            llParseString2List(data, ["&"], []),
            [ k + "=" + v ],
        i, i),
    "&");
    return data + "&" + k + "=" + v;
}
 
integer self;
 
default {
    state_entry() {
        self = (integer)llGetScriptName();
    }
 
    link_message(integer sender, integer num, string message, key id) {
        if(num == self) {
            vector position = (vector)wasKeyValueGet(
                "position", 
                message
            );
 
            integer param = (integer)wasKeyValueGet(
                "param",
                message
            );
 
            vector owner = llGetPos();
            rotation= llRotBetween(
                <1, 0, 0>,
                llVecNorm(
                    <
                        position.x - owner.x, 
                        position.y - owner.y, 
                        position.z - owner.z
                    >
                )
            );
 
            llRezObject(
                llGetInventoryName(INVENTORY_OBJECT, 0),
                position,
                ZERO_VECTOR,
                qΔ,
                param
            );
        }
    }
}

Missing Texture

The following texture is used to display an error state.