About

This is the converse of the environmental with medicine backpack applied to stress levels. In this variant, the bar starts at 0 on green and fills up progressively to 1000 on red. It is used in cases where you want the progress bar to start empty and eventually reach the top - perhaps something like danger meter.

Code

This script was tested and works on OpenSim version 0.7.4!

contagionstress.lsl
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2013 - 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) 2011 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasProgress(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);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU 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) >;
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2012 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
list wasDeleteSubListMatch(list in, string match) {
    if (llGetListLength(in) == 0) return [];
    string first = llList2String(in, 0);
    in = llDeleteSubList(in, 0, 0);
    if (llSubStringIndex(first, match) == -1) jump next;
    return wasDeleteSubListMatch(in, match);
@next;
    return first + wasDeleteSubListMatch(in, match);
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueGet(string k, string data) {
    if (llStringLength(data) == 0) return "";
    if (llStringLength(k) == 0) return "";
    list a = llParseStringKeepNulls(data, ["&", "="], []);
    integer i = llListFindList(a, [ k ]);
    if (i != -1) return llList2String(a, i + 1);
    return "";
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueSet(string k, string v, string data) {
    if (llStringLength(data) == 0) return k + "=" + v;
    if (llStringLength(k) == 0) return "";
    if (llStringLength(v) == 0) return "";
    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;
}
 
///////////////////////////////////////////////////////////////////////////
//    Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3    //
///////////////////////////////////////////////////////////////////////////
string wasKeyValueEncode(list data) {
    list k = llList2ListStrided(data, 0, -1, 2);
    list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2);
    data = [];
    do {
        data += llList2String(k, 0) + "=" + llList2String(v, 0);
        k = llDeleteSubList(k, 0, 0);
        v = llDeleteSubList(v, 0, 0);
    } while (llGetListLength(k) != 0);
    return llDumpList2String(data, "&");
}
 
// Quick function to list AoE.
string getExposures() {
    if (llGetListLength(exposures)) return "Exposures: " + "[ " + llDumpList2String(exposures, ",") + " ]";
    return "";
}
 
integer stress = 0;
integer damage = 0;
list exposures = [];
list penalties = [];
 
default
{
    state_entry() {
        stress = (integer)wasKeyValueGet("stress", llGetObjectDesc());
        integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6));
        llListen(comChannel, "Medicine Backpack", "", "");
        llSetTimerEvent(1);
        llSensorRepeat("", "", ACTIVE | PASSIVE, 96, TWO_PI, 1);
    }
 
    // When an AoE objects are detected, go through all off them and process them.
    sensor(integer num) {
        --num;
        do {
            // First grab the formatted name.
            string data = llDetectedName(num);
            // If the range of the AoE is smaller than the distance between the AV and the
            // trigger point, then remove the AoE exposure from the exposures list and continue.
            string dh = wasKeyValueGet("range", data);
            // If the object does not have a range set, it's not going to affect the avatar
            // and is most likely just a static object not part of the project. Quickly ignore.
            if (dh == "") jump continue;
            if (llVecDist(llGetPos(), llDetectedPos(num)) > (float)dh) jump continue;
            // Check if the exposure has a properly formatted name.
            dh = wasKeyValueGet("name", data);
            // If it doesn't ignore it, and jump to AoE processing.
            if (dh == "") jump exposure;
            // If it does, add it to the list of AoE exposures.
            if (llListFindList(exposures, (list)dh) == -1) {
                exposures += dh;
                jump exposure;
            }
            // If the exposure is already active, ignore the AoE (non-stacking AoE)
            return;
@exposure;
            // Check if the exposure has a properly formatted stress.
            dh = wasKeyValueGet("stress", data);
            // If it does not, ignore and continue and don't waste time.
            if (dh == "") jump continue;
            // Get the stress and add it to the current stress, either increasing or decreasing
            // while making sure that it doesn't underrun 0, respectively 100 (Hard cap).
            damage += (integer)dh;
            penalties += (integer)dh;
@continue;
        } while (--num > -1);
    }
 
    listen(integer channel, string name, key id, string message) {
        if (llGetOwnerKey(id) != llGetOwner()) return;
        string exposure = wasKeyValueGet(message, llGetObjectDesc());
        if (llStringLength(exposure) == 0) return;
        integer i = llListFindList(exposures, (list)exposure);
        if (i == -1) return;
        exposures = llDeleteSubList(exposures, i, i);
        integer d = llList2Integer(penalties, i);
        damage -= d;
        penalties = llDeleteSubList(penalties, i, i);
        llOwnerSay("You prevent the " + exposure + " exposure.");
    }
 
    // Every tick, display overhead status.
    timer() {
        stress += damage;
        if (stress <= 0) stress = 0;
        if (stress > 1000) stress = 1000;
        llSetObjectDesc(wasKeyValueSet("stress", (string)stress, llGetObjectDesc()));
        integer p = (integer)(100.0 * (float)stress / 1000.0);
        llSetText("Stress: " + wasProgress(p, 10, ["[", "█", "░", "]"]) + "\n" + getExposures(), wasPercentToGradient(p, "gr"), 1.0);
        llRegionSay(-2104156, wasKeyValueEncode(["owner", llKey2Name(llGetOwner()), "stress", p]));
    }
 
    // Restart the script on rez and attach to make sure that llGetOwner() returns a correct key (BUG)
    on_rez(integer num) {
        llResetScript();
    }
    attach(key id) {
        llResetScript();
    }
}

secondlife/contagion/stress.txt · Last modified: 2022/11/24 07:46 by 127.0.0.1

Access website using Tor Access website using i2p Wizardry and Steamworks PGP Key


For the contact, copyright, license, warranty and privacy terms for the usage of this website please see the contact, license, privacy, copyright.