cannon.lsl
//////////////////////////////////////////////////////////
//   (C) Wizardry and Steamworks 2011, license: GPLv3   //
// Please see: http://www.gnu.org/licenses/gpl.html     //
// for legal details, rights of fair usage and          //
// the disclaimer and warranty conditions.              //
//////////////////////////////////////////////////////////
 
//////////////////////////////////////////////////////////
// Wizardry and Steamworks (c) 2013,  GPLv3             //
//////////////////////////////////////////////////////////
 
string progress(integer percent, integer length, list symbols) {
    percent /= (integer)((float)100.0/(length));
    string p = llList2String(symbols,0);
    integer itra = 0;
    do {
        if(itra>percent-1) p += llList2String(symbols,2);
        else p += llList2String(symbols,1);
    } while(++itra<length);
    return p + llList2String(symbols,3);
}
 
//////////////////////////////////////////////////////////
// Wizardry and Steamworks (c) 2013,  GPLv3             //
//////////////////////////////////////////////////////////
 
vector wasPercentToGradient(float percent, string rgb) {
    if(llStringLength(rgb) != 2) {
        llSay(DEBUG_CHANNEL, "Assert failed, rgb parameter must consist of a pair of either r, g, or b.");
        return ZERO_VECTOR;
    }
    string a = llGetSubString(rgb, 0, 0);
    string b = llGetSubString(rgb, 1, 1);
    list col = [ "r", "g", "b" ];
    integer ax = llListFindList(col, (list)a);
    integer bx = llListFindList(col, (list)b);
    if(ax == -1 || bx == -1) {
        llSay(DEBUG_CHANNEL, "Asset failed, rgb parameters must contain either r, g, or b letters.");
        return ZERO_VECTOR;
    }
    col = llListReplaceList(col, (list)((100-percent)/100), ax, ax);
    col = llListReplaceList(col, (list)(percent/100), bx, bx);
    return 2*<llList2Float(col, 0), llList2Float(col, 1), llList2Float(col, 2)>;
}
 
 
float power = 10;
 
default {
    state_entry() {
        power = 10;
        state arm;
    }
}
 
state arm {
    state_entry() {
        // alarm 5
        llPreloadSound("Cannon");
        llSetTimerEvent(5);
    }
    touch_start(integer num) {
        llSetTimerEvent(0);
    }
    touch(integer num) {
        if(power > 30) return;
        power+=0.3;
        integer percent = (integer)((power-10)*100.0/20.0);
        vector rt = llRot2Euler(llGetLocalRot());
        string range = llGetSubString((string)(2 * llPow(power, 2) * llCos(rt.z) * llSin(rt.z) / 9.81), 0, 4) + "m";
        llSetText("☉ Power ☉\n" + progress(percent, 20, ["[", "█", "░", "]"]) + "\n" +
                    "Range: " + range, wasPercentToGradient(percent, "gr"), 1.0);
    }
    touch_end(integer num) {
        state release;
    }
    timer() {
        llSetText("", <1,1,1>, 1.0);
    }
}
 
state release {
    state_entry() {
        llPlaySound("Cannon", 1.0);
        llRegionSay(-90, "rez");
        llRezObject("Particle", llGetPos(), <power,0,0> * llGetRot(), ZERO_ROTATION, 0);
        state default;
    }
}