Myriad Meter
updated February 10 2012
//============================================================================
// Myriad Lite Meter v0.0.4 20110903
// Copyright (c) 2011 By Allen Kerensky (OSG/SL)
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad is published under a:
// Creative Commons License (Attribution 2.0 UK: England and Wales)
// Myriad Lite Meter is published under a:
// Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported
//============================================================================

//============================================================================
// MESSAGE FORMAT REFERENCE
//============================================================================
// CHANPLAYER IN - METER|str PLAYER NAME|str GAMENAME|int CURWOUNDS|int MAXWOUNDS|int CURCRITICAL|int MAXCRITICAL|int ISDEAD|int ISINCAPACITATED

//============================================================================
// GLOBAL VARIABLES
//============================================================================
integer CHANATTACH; // dynamic channel for player attachments 
integer HANDATTACH; // attach channel handle for llRemove
string DIV = "|"; // Myriad message field divider
string  STATUS; // settext message
integer NAME_FORMAT = 1; // 1 = Alias only, 2 = First "Alias" Last, 3 = Alias (First Last)
integer SHOW_HEALTH = TRUE; // show the health percentage or not?
vector  COLOR = <0,1,0>; // set text color
float   ALPHA = 1.0; // set text alpha 0.0 = clear, 1.0 = solid
vector GREEN = <0,1,0>; // color constant for convenience
vector YELLOW = <1,1,0>; // color constant for convenience
vector RED = <1,0,0>; // color constant for convencience
vector BLACK = <0,0,0>; // color constant for convenience

//============================================================================
// GLOBAL SETUP()
//============================================================================
SETUP() {
    llSetText("--- Waiting for Myriad Update ---",<1,0,0>,1); // set a default banner to show we haven't been updated yet
    CHANATTACH = (integer)("0x"+llGetSubString((string)llGetOwner(),1,7)); // calculate wearer's dynamic attachment channel
    if ( HANDATTACH != 0 ) llListenRemove(HANDATTACH); // remove previously open channel
    HANDATTACH = llListen(CHANATTACH,"",NULL_KEY,""); // start a listener on the dynamic channel
    llWhisper(CHANATTACH,"ATTACHMETER"); // tell HUD we're attached
}

//============================================================================
// DEFAULT STATE
//============================================================================
default {
    //------------------------------------------------------------------------
    // STATE_ENTRY EVENT
    //------------------------------------------------------------------------    
    state_entry() {
        SETUP(); // setup the hovertext meter
    }

    //------------------------------------------------------------------------
    // ON_REZ EVENT
    //------------------------------------------------------------------------    
    on_rez(integer start_param) {
        SETUP(); // setup the hovertext meter
    }

    //------------------------------------------------------------------------
    // ATTACH EVENT
    //------------------------------------------------------------------------    
    attach(key id) { // 
        if ( id != NULL_KEY ) {
            SETUP(); // wearing, let's setup
            return;
        }
        if ( id == NULL_KEY ) { // detach, drop, derezzed to inventory - NOT ON LOGOUT
            if ( HANDATTACH != 0 ) llListenRemove(HANDATTACH);
            llWhisper(CHANATTACH,"DETACHMETER");
            return;
        }
    }
    //------------------------------------------------------------------------
    // CHANGED EVENT
    //------------------------------------------------------------------------    
    changed(integer changes) {
        if ( changes & CHANGED_OWNER ) { // if owner has changed, we need to recalculate the dynamic channel
            SETUP(); // setup the hovertext meter
            return;
        }
        if ( changes & CHANGED_REGION || changes & CHANGED_TELEPORT ) { // owner jumped to new location? restart
            SETUP(); // setup hovertext and channel
            return;
        }
    }

    //------------------------------------------------------------------------
    // LISTEN EVENT
    //------------------------------------------------------------------------    
    listen(integer channel,string name,key id,string message) {
        if ( channel == CHANATTACH ) { // did this message come in on attachment channel?
            list fields = llParseString2List(message,[DIV],[]); // break message down into list separated by |
            string command = llList2String(fields,0); // read first item in list to get the Myriad command
            if ( command == "METER") { // if this is the METER command, let's update the meter status
                string dead = "no"; // set a default of "not dead"
                string incap = "no"; // set a default of "not incapacitated"
                string playername   = llList2String(fields,1); // get the full player name from the list of METER values
                list   name2        = llParseString2List(playername,[" "],[]); // separate first and last name by space
                string firstname    = llList2String(name2,0); // get the firstname from the name2
                string lastname     = llList2String(name2,1); // get the lastname, if any, from the name2
                string gamename     = llList2String(fields,2); // get player's alias/game name (originally set in their character sheet)
                integer curwounds   = llList2Integer(fields,3); // what is player's current wound value?
                integer maxwounds   = llList2Integer(fields,4); // what is player's maximum healed wounds allowed by level/stats?
                integer curcritical = llList2Integer(fields,5); // what is player's current critical wounds value?
                integer maxcritical = llList2Integer(fields,6); // what is player's maximum healed critical wounds value?
                integer isdead      = llList2Integer(fields,7); // is player dead?
                integer isincap     = llList2Integer(fields,8); // is player incapacitated?
                // okay, we've broken down status, lets create a banner from that using colors
                STATUS = ""; // start with an empty string
                COLOR = GREEN; // start with fully healthy color
                if ( NAME_FORMAT == 1 ) { // what name format do we want to see?                
                    STATUS = gamename; // 1 == just Alias name from character sheet
                } else if ( NAME_FORMAT == 2 ) { // not format 1, so format 2?
                    STATUS = firstname + "\"" + gamename + "\"" + lastname; // firstname "alias" lastname
                } else if ( NAME_FORMAT == 3 ) { // not format 1, or 2, so...
                    STATUS = gamename + "("+playername+")"; // alias (firstname lastname)
                }
                if ( SHOW_HEALTH == TRUE ) { // do we want a health number (unrealistic)
                    float currentpoints = (float)curwounds + (float)curcritical; // add up noncritical and critical wounds boxes remaining
                    float maxpoints = (float)maxwounds + (float)maxcritical; // add up total wounds boxes player should have
                    if ( currentpoints > 0.0 ) { // if player has some wounds left
                        float health = ( ( currentpoints / maxpoints ) * 100.0 ); // get a percentage
                        STATUS += "\nHealth: "+(string)llRound(health)+"%"; // add the percentage health to the status
                    } else { // oops all resilience gone
                        STATUS += "\nHealth; 0%"; // so add a zero% to status
                    }
                }
                if ( curwounds == maxwounds && curcritical == maxcritical ) { // are all health boxes full?
                    COLOR = GREEN; // fully healthy
                }
                if ( curwounds < maxwounds && curwounds >= 1 ) { // we've lost some wounds, but not incapacitated
                    COLOR = YELLOW; // set a warning that we've been wounded and not fully healty
                }
                if ( curwounds < 1 ) { // if we're out of non-critical wounds, we're in trouble
                    COLOR = RED; // we're incapacitated but not dead, bleeding out here
                }
                if ( isincap == 1 && isdead == 0 ) {
                    STATUS += " ! INCAPACITATED !";
                    COLOR = RED; // set color to warning that we're down but not dead yet
                }
                if ( isdead == 1 ) {  // if we're dead
                    STATUS += " !!! DEAD !!!"; // add a notice to status
                    COLOR = BLACK; // set color to color of death
                }                
                llSetText(STATUS,COLOR,ALPHA); // show the new status text over the meter
                return; // we're done with this command, exit entire listen event
            } // end if command meter
            if ( command == "REGISTERATTACHMENTS" ) { // HUD asking for attachments attached?
                SETUP(); // just setup
            }
        } // end if chanattach
    }
} // end default
//============================================================================
// END
//============================================================================
Creative Commons License
This work by