User:Allen Kerensky/Myriad Lite Preview 5/Module Armor

From OpenSimulator

< User:Allen Kerensky | Myriad Lite Preview 5
Revision as of 08:16, 6 February 2012 by Allen Kerensky (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Myriad Lite Module: Armor

Armor is never a bad idea if you are in a place where combat is likely.

Unlike many game systems, armor does not make you harder to hit.

Armor deflects kinetic impact damage away from you (armor glancing) or absorbs some or all of the damage on a hit.

Some armor is static, just a simple object like a medieval shield or bulletproof vest.

In science-fiction, armor may be computerized or formed from an electronic field.

Myriad Lite calls armor that requires energy to run "power armor"

Example Armor

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

Quick Start

  • (required) Wear the Myriad Lite HUD.
  • (optional) Wear the hovertext meter
  • (optional) Wear armor, which you should see reported in your chat window.
  • (optional) Wear a holster
  • (optional) Wear a melee or ranged combat weapon

Commands

Myriad Lite accepts a variety of chat commands on channel 5.

/5 <command> will activate that command. Scripters can also send the same commands as a link message. Custom HUDs can be constructed with buttons named each command, and the button will activate the command of the same name

Armor Commands

Armor commands are detailed below in context.

For non-powered armor, simply wear the item and you should see the armor value reported. /5 checkarmor to see what your current armor value is

The following commands let you control power armor:

  • /5 armoron to activate power armor.
  • /5 armoroff to deactivate power armor and save the battery
  • /5 recharge to recharge a power armor battery

Creating Armor

  1. Save the Armor script below into your inventory.
  2. Create an object to represent a piece of armor, such as a bracelet or helmet.
  3. Drag and Drop the Myriad Lite Armor script from inventory into the attachment.
  4. (optional) Edit the script to adjust:
    1. (optional) Rating from 1-5
    2. (optional) Whether or not this is a piece of power armor
    3. (optional) How much battery life this armor has before recharging
    4. Attach the armor and adjust the position
  5. Detach the piece of armor back into inventory again to "save" the default attach point.
  6. Attach/wear the armor piece when desired.

NOTE: The Myriad Lite HUD should report the armor registering as a change in armor value.

Myriad_Lite_Armor-v0.0.5-20120130.lsl

//============================================================================
// Myriad_Lite_Armor_v0.0.5-20120130.lsl
// Copyright (c) 2012 By Allen Kerensky (OSG/SL)
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
// Myriad RPG licensed under the Creative Commons Attribution 2.0 UK: England and Wales
// http://creativecommons.org/licenses/by/2.0/uk/
// Myriad Lite software Copyright (c) 2011 by Allen Kerensky (OSG/SL)
// Baroun's Adventure Machine Copyright (c) 2008-2011 by Baroun Tardis (SL)
// Myriad Lite and Baroun's Adventure Machine licensed under the
// Creative Commons Attribution-Share Alike-Non-Commercial 3.0 Unported
// http://creativecommons.org/licenses/by-nc-sa/3.0/
// You must agree to the terms of this license before making any use of this software.
// If you do not agree to this license, simply delete these materials.
// There is no warranty, express or implied, for your use of these materials.
//============================================================================

//============================================================================
// 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
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 = FALSE; // does this armor burn power?
integer MAXBATTERY = 3600; // how many seconds can armor run before recharge?

//============================================================================
// RUNTIME VARIABLES - variables which should change during runtime
//============================================================================
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 = TRUE; // is armor "on" and protecting?
integer BATTERY; // current charge left for power armor
integer EFFECTTIME; // how much time is left to show armor effects

//============================================================================
// DEBUG - show debug chat with wearer name for sorting
//============================================================================
DEBUG(string dmessage) {
    llOwnerSay("DEBUG: "+dmessage);
}

//============================================================================
// 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

    // end of special effects
    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
        
    // end of special effects
    EFFECTTIME = MAXEFFECTTIME; // load the countdown
}

//============================================================================
// EFFECTOFF - RESET ARMOR TO NORMAL VIEW
//============================================================================
EFFECTOFF() {
    // your commands go here to turn off armor effects

    // end of armor reset
}

//============================================================================
// ARMOR ON - ACTIVATE POWERED ARMOR
//============================================================================
ARMORON() {
    if ( POWERARMOR != TRUE ) {
        llOwnerSay("Cannot activate non-powered armor.");
        return;
    }
    if ( BATTERY <= 0 ) {
        llOwnerSay("Armor out of power. Recharge.");
        return;
    }
    ARMOR_ON = TRUE;
    // your special effect code here
    llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES);
    llSetTimerEvent(1.0); // run a battery drain timer, battery already checked > 0
}

//============================================================================
// ARMOR OFF - DEACTIVATE POWERED ARMOR
//============================================================================
ARMOROFF() {
    if ( POWERARMOR != TRUE ) {
        llOwnerSay("Cannot deactivate non-powered armor.");
        return;
    }
    ARMOR_ON = FALSE;
    llOwnerSay("Power armor shutting down.");
    // your code here
    llSetLinkAlpha(LINK_SET,0.0,ALL_SIDES);
}

//============================================================================
// CHECK BATTERY
//============================================================================
CHECKBATTERY() {
    if ( POWERARMOR != TRUE ) {
        llOwnerSay("Cannot check battery level for non-powered armor.");
        return;
    }
    llOwnerSay("Armor battery level: "+(string)BATTERY+" of "+(string)MAXBATTERY+" total.");
}

//============================================================================
// RECHARGE POWER ARMOR BATTERY
//============================================================================
RECHARGE() {
    if ( POWERARMOR != TRUE ) {
        llOwnerSay("Cannot recharge non-powered armor.");
        return;
    }
    // TODO Partial Recharges?
    BATTERY = MAXBATTERY;
    llOwnerSay("Armor recharged.");
}

//============================================================================
// GLOBAL SETUP()
//============================================================================
SETUP() {
    // calculate a dynamic chat channel based on owner key, for where the
    // wearer's ML HUD should be listening of attachment -specific events
    CHANATTACH = (integer)(CHAN_PREFIX+llGetSubString((string)llGetOwner(),1,7));
    // open a channel, listening on player HUD channel, save handle for later close if needed
    HANDATTACH = llListen(CHANATTACH,"",NULL_KEY,"");
    if ( POWERARMOR == TRUE ) BATTERY = MAXBATTERY; // charge the battery to full
    llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES); // show the armor
}

//============================================================================
// 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) {
        SETUP(); // call event-independent SETUP code
        // is this an attach event or detach event?
        if ( id != NULL_KEY ) { // a valid key means its an attach
            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
            // however, armor can be dropped! So, wearer may NOT be owner. Need changed block?
            integer dynchan = (integer)("0x"+llGetSubString((string)WEARER,1,7));
            // Send ATTACHARMOR message to WEARER HUD
            llWhisper(dynchan,"ATTACHARMOR"+DIV+(string)ARMORRATING+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
        } else { // else the id equals NULL_KEY which happens for detach
            // calculate dynamic channel for person last wearing armor piece
            integer dynchan = (integer)("0x"+llGetSubString((string)WEARER,1,7));
            if ( dynchan != 0 ) { // did the dynamic channel check give us usable channel number <0 or >0 but not actually 0?
                // Send DETACHARMOR message to previous wearer's HUD
                llWhisper(dynchan,"DETACHARMOR"+DIV+(string)ARMORRATING+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
            } else { // the dynamic channel was 0?
                // how did we get in this mess? a detach without an attach. Report error. Design failure somewhere. THIS SHOULD NEVER HAPPEN.
                DEBUG("DETACH EVENT WITHOUT PREVIOUS ATTACH?");
            } // end of if dynchan not equal zero
            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
        } // end of if id not equal null key
    }
    //------------------------------------------------------------------------
    // 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
            llResetScript(); // restart attachment after region change or teleport
        }
    }    
    //------------------------------------------------------------------------
    // 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
        if ( channel == CHANATTACH ) { // is this message on the attach channel?
            if ( message == "ARMORHIT" ) { // is this an armor hit?
                EFFECTHIT(); // turn on armor hit effects
                return; // message processed, exit early
            }
            if ( message == "ARMORBLOCKED" ) { // did the armor block the hit too
                EFFECTBLOCKED(); // turn on armor block effects
                return; // message processed, exit early
            }
            // ML HUD sent a request for any attached items
            if ( ( message == "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)("0x"+llGetSubString((string)WEARER,1,7));
                // send the ATTACHARMOR to ML HUD to register that this armor piece is worn
                llWhisper(dynchan,"ATTACHARMOR"+DIV+(string)ARMORRATING+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
                return; // message processed, exit early
            } // end of if message equal REGISTERATTACHMENTS            
            if ( message == "ARMORON" ) { ARMORON(); return;} // activate power armor
            if ( message == "ARMOROFF" ) { ARMOROFF(); return;} // deactivate power armor
            if ( message == "RECHARGE" ) { RECHARGE(); return;} // recharge power armor battery?
            if ( message == "CHECKBATTERY" ) { CHECKBATTERY(); return;} // check battery level
        } // 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 ( POWERARMOR == TRUE && ARMOR_ON == TRUE ) {
            BATTERY--; // remove some battery
            if ( BATTERY <= 0 ) {
                llOwnerSay("Armor battery drained. Shutting down.");
                ARMOROFF(); // turn off armor
            }
        }
        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