User:Allen Kerensky/Myriad Lite/Myriad Lite Armor-Preview6.lsl

From OpenSimulator

Jump to: navigation, search

Myriad_Lite_Armor-Preview6.lsl

//============================================================================
// Myriad_Lite_Armor_Preview6.lsl 
// Copyright (c) 2012 by Allen Kerensky (OSG/SL) All Rights Reserved.
// This work is dual-licensed under
// Creative Commons Attribution (CC BY) 3.0 Unported
// http://creativecommons.org/licenses/by/3.0/
// - or -
// Modified BSD License (3-clause)
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice, 
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Myriad Lite nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
// NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG System licensed under:
// Creative Commons Attribution (CC BY) 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
//============================================================================
 
//============================================================================
// MESSAGE FORMATS
//============================================================================
// CHANATTACH - IN - REGISTERATTACHMENTS
// CHANATTACH - OUT - ATTACHARMOR|int ARMORRATING|int ATTACHPOINT|string OBJECTNAME
// CHANATTACH - OUT - DETACHARMOR|int ARMORRATING|int ATTACHPOINT|string OBJECTNAME
// CHANATTACH - IN - ARMORHIT
// CHANATTACH - IN - ARMORBLOCKED
// CHANATTACH - IN - ARMORON
// CHANATTACH - IN - ARMOROFF
// CHANATTACH - IN - CHECKBATTERY
// CHANATTACH - IN - RECHARGE
 
//============================================================================
// CONSTANTS - variables which don't change over runtime
//============================================================================
// Example Armor (Myriad PDF p64, Myriad Special Edition p98)
// Archaic Armor Ratings
// 1 Soft leather, heavy cloth
// 2 Hardened leather, thick hide
// 3 Chain mail, dragon hide
// 4 Full plate mail, mithril chain
// 5 Mithril plate mail
// Modern Armor Ratings
// 1 Leather jacket
// 2 Bullet-proof vest
// 3 SWAT tactical armor
// 4 Advanced military armor
// 5 Sci-fi powered battle armor
 
string  VERSION = "0.0.6"; // version number
string  VERDATE = "20120212"; // version date
 
integer ARMORRATING = 1; // the *actual* amount of protection THIS piece of armor provides
string  CHAN_PREFIX = "0x"; // channel prefix to convert to hexadecimal
string  DIV="|"; // the divider used between fields on a Myriad Lite messages
integer MINATTACHPOINT = 1; // minimum allowed attachment point number
integer MAXATTACHPOINT = 30; // maximum allowed avatar/inworld attachpoint number for multiattach/HUD attach cheaters
integer MAXEFFECTTIME = 3; // maximum time to show armor hit/blocked effects
integer POWERARMOR; // does this armor burn power? configured in SETUP()
 
//============================================================================
// RUNTIME VARIABLES - variables which should change during runtime
//============================================================================
integer FLAG_DEBUG; // see debugging messages? Configured in SETUP();
key     WEARER = NULL_KEY; // holds UUID of last wearer, so we can send detach message to correct meter
integer ATTACHPOINT = 0; // the avatar position where armor attached to or detached from
integer CHANATTACH; // owner's attachment channel
integer HANDATTACH; // chat handle for attachment channel
integer ARMOR_ON; // is armor "on" and protecting when worn? configured in SETUP()
integer EFFECTTIME; // how much time is left to show armor effects
 
//============================================================================
// GLOBAL SETUP()
//============================================================================
SETUP() {
    FLAG_DEBUG = FALSE; // do we want debugging?
    ARMOR_ON = TRUE; // is power armor on and protecting by default
    POWERARMOR = TRUE; // is this a piece of power armor or not?
    WEARER = llGetOwner(); // set the default wearer key
    // calculate a dynamic chat channel based on owner key, for where the
    // wearer's ML HUD should be listening of attachment -specific events
    CHANATTACH = ATTACHCHANNEL(llGetOwner());
    // open a channel, listening on player HUD channel, save handle for later close if needed
    if ( HANDATTACH != 0 ) llListenRemove(HANDATTACH); // close an existing listerner first
    HANDATTACH = llListen(CHANATTACH,"",NULL_KEY,"");
}
 
//============================================================================
// DEBUG - show debug chat with wearer name for sorting
//============================================================================
DEBUG(string dmessage) {
    if ( FLAG_DEBUG == TRUE ) llOwnerSay("DEBUG: ("+llKey2Name(WEARER)+"): "+dmessage);
}
 
//============================================================================
// RESET() - wrap the llResetScript so we can persist data if needed
//============================================================================
RESET() {
    llResetScript();
}
 
//============================================================================
// VERSION
//============================================================================
GETVERSION() {
    integer dynchan = ATTACHCHANNEL(llGetOwner());
    llWhisper(dynchan,"VERSION="+VERSION+DIV+"VERSIONDATE="+VERDATE+DIV+llGetObjectName());
}
 
//============================================================================
// ATTACHCHANNEL - calculate dynamic channels
//============================================================================
integer ATTACHCHANNEL(key forwho) {
    // FIXME validate key does if (uuid) work in OSgrid?
    if ( forwho == NULL_KEY ) return 0; // not valid
    return ((integer)(CHAN_PREFIX+llGetSubString((string)forwho,1,7)));
}
 
//============================================================================
// ARMOR ON - ACTIVATE POWERED ARMOR
//============================================================================
ARMORON() {
    ARMOR_ON = TRUE;
    // your commands go here for armor special effect when starting up
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
}
 
//============================================================================
// ARMOR OFF - DEACTIVATE POWERED ARMOR
//============================================================================
ARMOROFF() {
    if ( POWERARMOR == FALSE ) return;
    ARMOR_ON = FALSE;
    // your commands go here for armor special effect when shutting down
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
    // ***
}
 
//============================================================================
// ARMORBATTERY() - SHOW SPECIAL ARMOR EFFECTS WHEN CHECKIGN ARMOR BATTERY LEVEL
//============================================================================
ARMORBATTERY() {
    // your commands go here for armor special effect when checking armor battery
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
}
 
//============================================================================
// ARMORRECHARGE() - SHOW SPECIAL ARMOR EFFECTS WHEN RECHARGING ARMOR BATTERY LEVEL
//============================================================================
ARMORRECHARGE() {
    // your commands go here for armor special effect when recharging
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
}
 
//============================================================================
// ARMORBATTERY() - SHOW SPECIAL ARMOR EFFECTS WHEN CHECKING ARMOR PROTECTION RATING
//============================================================================
ARMORCHECK() {
    // your commands go here for armor special effect when checking armor protection rating
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
}
 
//============================================================================
// EFFECTHIT() - SHOW SPECIAL ARMOR EFFECTS WHEN ARMOR HIT BUT FAILS TO BLOCK
//============================================================================
EFFECTHIT() {
    // your commands go here for armor special effect when armor hit and does not block
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
    EFFECTTIME = MAXEFFECTTIME; // load the countdown
}
 
//============================================================================
// EFFECTBLOCKED - CHANGE ARMOR EFFECT WHEN ARMOR HIT AND BLOCKS DAMAGE
//============================================================================
EFFECTBLOCKED() {
    // your commands go here for armor special effect when armor BLOCKS a hit
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
    // ***        
    EFFECTTIME = MAXEFFECTTIME; // load the countdown
}
 
//============================================================================
// EFFECTOFF - RESET ARMOR TO NORMAL VIEW
//============================================================================
EFFECTOFF() {
    // your commands go here to turn off armor effects
    // *** BEGIN your special effect code here
    // ***
    // *** END your special effect code here
    // ***
}
 
//============================================================================
// DEFAULT
//============================================================================
default {
    //------------------------------------------------------------------------
    // DEFAULT STATE ENTRY - begin our setup or call a setup block
    //------------------------------------------------------------------------
    state_entry() {
        SETUP(); // call the event-independent SETUP code
    }
    //------------------------------------------------------------------------
    // DEFAULT ON_REZ
    //------------------------------------------------------------------------
    on_rez(integer start_param) {
        start_param = 0; // LSLINT
        SETUP(); // call event independent SETUP code        
    }
    //------------------------------------------------------------------------
    // DEFAULT ATTACH - Called for detach too
    //------------------------------------------------------------------------
    attach(key id) {
        DEBUG("attach("+(string)id+")");
        if ( id == NULL_KEY ) { // on detach act fast
            llWhisper((integer)(CHAN_PREFIX+llGetSubString((string)llGetOwner(),1,7)),"ARMORDETACH"+DIV+(string)ARMORRATING+DIV+(string)POWERARMOR+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
            WEARER = NULL_KEY; // armor detached and reported as such, so we can forget previous wearer
            ATTACHPOINT = 0; // armor detached and reported as such, so we can forget previous attach point
            return;
        } // end of if id not equal null key    
        // is this an attach event or detach event?
        if ( id != NULL_KEY ) { // a valid key means its an attach
            SETUP(); // call event-independent SETUP code
            WEARER = id; // save who attached this armor piece for use during detach
            ATTACHPOINT = llGetAttached(); // where was this armor attached?
            // this should NOT be necessary, since it should match CHANPLAYER
            integer dynchan = ATTACHCHANNEL(WEARER);
            // send the ATTACHARMOR to ML HUD to register that this armor piece is worn
            llWhisper(dynchan,"ARMORATTACH"+DIV+(string)ARMORRATING+DIV+(string)POWERARMOR+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
            return;
        }
    }
    //------------------------------------------------------------------------
    // DEFAULT CHANGED
    //------------------------------------------------------------------------
    changed(integer change) {
        if ( change & CHANGED_OWNER ) { // if armor has a new owner from take-from-ground or copy, resetup
            SETUP(); // call event-independent setup code, in this case to update channels
        }
        if ( ( change & CHANGED_REGION ) || ( change & CHANGED_TELEPORT ) ) {
            EFFECTOFF(); // stop effects before reset
            // FIXME - resets battery state
            RESET();
        }
    }    
    //------------------------------------------------------------------------
    // DEFAULT LISTEN
    //------------------------------------------------------------------------
    listen(integer channel,string speakername,key speakerid,string message) {
        speakername = ""; // LSLINT
        speakerid = NULL_KEY; // LSLINT
        ATTACHPOINT = llGetAttached(); // get location we're attached to
        list tokens = llParseString2List(message,["|"],[]);
        string command = llToLower(llStringTrim(llList2String(tokens,0),STRING_TRIM));
        if ( channel == CHANATTACH ) { // is this message on the attach channel?
            // General Myriad Lite System Commands
            if ( command == "reset" ) { RESET(); return; }
            if ( command == "version" ) { GETVERSION(); return; }
            if ( command == "debugon" ) { FLAG_DEBUG = TRUE; DEBUG("on"); return; }
            if ( command == "debugoff" ) { FLAG_DEBUG = FALSE; DEBUG("off"); return; }
            // Armor Commands
            if ( ( command == "registerattachments" ) && ( ATTACHPOINT >= MINATTACHPOINT ) && ( ATTACHPOINT <= MAXATTACHPOINT ) ) {
                WEARER = llGetOwner(); // get armor owner BUG: what if owner not equal wearer?
                // calculate the dynamic channel of the wearer
                integer dynchan = (integer)(CHAN_PREFIX+llGetSubString((string)WEARER,1,7));
                // send the ATTACHARMOR to ML HUD to register that this armor piece is worn
                llWhisper(dynchan,"ARMORATTACH"+DIV+(string)ARMORRATING+DIV+(string)POWERARMOR+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
                return; // message processed, exit early
            } // end of if message equal REGISTERATTACHMENTS
            if ( command == "armorreset" ) { RESET(); return;} // reset armor
            if ( command == "armoron" ) { ARMORON(); return;} // activate power armor
            if ( command == "armoroff" ) { ARMOROFF(); return;} // deactivate power armor
            if ( command == "armorbattery" ) { ARMORBATTERY(); return;} // show effects on armor battery level check
            if ( command == "armorrecharge" ) { ARMORRECHARGE(); return;} // show effects on armor recharge
            if ( command == "armorcheck" ) { ARMORCHECK(); return;} // show effects on armor check            
            if ( command == "armoreffecthit" ) { EFFECTHIT(); return; } // is this an armor hit?
            if ( command == "armoreffectblocked" ) { EFFECTBLOCKED(); return; } // did the armor block the hit too
            if ( command == "armoreffectoff" ) { EFFECTOFF(); return; } // time to turn off effects?
            // ML HUD sent a request for any attached items
        } // end if channel CHANATTACH
    } 
 
    //------------------------------------------------------------------------
    // TIMER CALLED TO TURN OFF THE SPECIAL EFFECTS
    //------------------------------------------------------------------------
    timer() {
        EFFECTTIME--;
        if ( EFFECTTIME <= 0 ) { 
            EFFECTOFF(); // turn off special effects
            EFFECTTIME=0; // make it zero anyway
        } // timer expired, turn off effect
        if ( EFFECTTIME <= 0 || ARMOR_ON == FALSE ) llSetTimerEvent(0.0); // all timers done, stop timer events
    } // end timer
} // end default
//============================================================================
// END
//============================================================================
Personal tools
General
About This Wiki