This is a version of the script that detects, adds and subtracts health points depending on the objects in the environment.
/////////////////////////////////////////////////////////////////////////// // 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) 2015 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(llList2ListStrided(a, 0, -1, 2), [ k ]); if(i != -1) return llList2String(a, 2*i+1); return ""; } /////////////////////////////////////////////////////////////////////////// // 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); } // Quick function to list AoE. string getEffects() { if(llGetListLength(effects)) return "Effects: " + "[ " + llDumpList2String(effects, ",") + " ]"; return ""; } integer health = 100; list effects = []; default { state_entry() { 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 effect from the effects 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) { // AoE effect range does not reach us, delete it if in effects and continue. string name = wasKeyValueGet("name", data); if(llListFindList(effects, (list)name) != -1) { effects = wasDeleteSubListMatch(effects, name); } jump continue; } // Check if the effect has a properly formatted name. dh = wasKeyValueGet("name", data); // If it doesn't ignore it, and jump to AoE processing. if(dh == "") jump effect; // If it does, add it to the list of AoE effects. if(llListFindList(effects, (list)dh) == -1) { effects += dh; jump effect; } // If the effect is already active, ignore the AoE (non-stacking AoE) return; @effect; // Check if the effect has a properly formatted health. dh = wasKeyValueGet("health", data); // If it does not, ignore and continue and don't waste time. if(dh == "") jump continue; // Get the health and add it to the current health, either increasing or decreasing // while making sure that it doesn't underrun 0, respectively 100 (Hard cap). integer mod = (integer)dh; if(health + mod > 100) { health = 100; jump continue; } if(health + mod < 0) { health = 0; jump continue; } // It does not overstep, so just perform the arithmetic. health += mod; @continue; } while(--num>-1); } // If no AoE objects are detected, consequently wipe the list. no_sensor() { effects = []; } // 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(); } // Every tick, display overhead status. timer() { llSetText("Health: " + wasProgress(health, 10, ["[", "█", "░", "]"]) + "\n" + getEffects(), wasPercentToGradient(health, "rg"), 1); } }