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

From OpenSimulator

< User:Allen Kerensky | Myriad Lite Preview 5(Difference between revisions)
Jump to: navigation, search
(created)
 
(fixed page to be about the HUD Module rather than armor attachment... oops)
Line 1: Line 1:
 
= Myriad Lite Module: Armor =
 
= Myriad Lite Module: Armor =
  
Armor is never a bad idea if you are in a place where combat is likely.
+
The Myriad Lite Module Armor script (below) goes into the [[User:Allen_Kerensky:Myriad_Lite_Preview_5:Myriad_Lite|Myriad Lite HUD]].
  
Unlike many game systems, armor does not make you harder to hit.
+
More information such as API messages will be in a later Preview release.
  
Armor deflects kinetic impact damage away from you (armor glancing) or absorbs some or all of the damage on a hit.
+
== Myriad_Lite_Module_Armor-v0.0.5-20120130.lsl ==
 
+
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 ===
+
# Soft leather, heavy cloth
+
# Hardened leather, thick hide
+
# Chain mail, dragon hide
+
# Full plate mail, mithril chain
+
# Mithril plate mail
+
 
+
=== Modern Armor Ratings ===
+
# Leather jacket
+
# Bullet-proof vest
+
# SWAT tactical armor
+
# Advanced military armor
+
# 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 ==
+
 
+
# Save the Armor script below into your inventory.
+
# Create an object to represent a piece of armor, such as a bracelet or helmet.
+
# Drag and Drop the Myriad Lite Armor script from inventory into the attachment.
+
# (optional) Edit the script to adjust:
+
## (optional) Rating from 1-5
+
## (optional) Whether or not this is a piece of power armor
+
## (optional) How much battery life this armor has before recharging
+
## Attach the armor and adjust the position
+
# Detach the piece of armor back into inventory again to "save" the default attach point.
+
# 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 ==
+
 
  <nowiki>
 
  <nowiki>
//============================================================================
+
// Myriad_Lite_Module_Armor-v0.0.0-20120125.lsl
// Myriad_Lite_Armor_v0.0.5-20120130.lsl
+
 
// Copyright (c) 2012 By Allen Kerensky (OSG/SL)
 
// Copyright (c) 2012 By Allen Kerensky (OSG/SL)
 
// The Myriad RPG System was designed, written, and illustrated by Ashok Desai
 
// 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
 
// Myriad RPG licensed under the Creative Commons Attribution 2.0 UK: England and Wales
 
// http://creativecommons.org/licenses/by/2.0/uk/
 
// http://creativecommons.org/licenses/by/2.0/uk/
// Myriad Lite software Copyright (c) 2011 by Allen Kerensky (OSG/SL)
+
// Myriad Lite software Copyright (c) 2011-2012 by Allen Kerensky (OSG/SL)
 
// Baroun's Adventure Machine Copyright (c) 2008-2011 by Baroun Tardis (SL)
 
// Baroun's Adventure Machine Copyright (c) 2008-2011 by Baroun Tardis (SL)
 
// Myriad Lite and Baroun's Adventure Machine licensed under the
 
// Myriad Lite and Baroun's Adventure Machine licensed under the
Line 88: Line 20:
 
// If you do not agree to this license, simply delete these materials.
 
// 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.
 
// There is no warranty, express or implied, for your use of these materials.
//============================================================================
 
  
//============================================================================
+
key PLAYERID = NULL_KEY; // cached player UUID
// 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
+
  
//============================================================================
+
integer LM_ATTACHARMOR  = 0x80000000;
// CONSTANTS - variables which don't change over runtime
+
integer LM_DETACHARMOR  = 0x80000001;
//============================================================================
+
integer LM_ARMORCURRENT  = 0x80000002;
// Example Armor (Myriad PDF p64, Myriad Special Edition p98)
+
integer LM_ARMORRESET    = 0x80000003;
// Archaic Armor Ratings
+
integer LM_ARMORON      = 0x80000004;
// 1 Soft leather, heavy cloth
+
integer LM_ARMOROFF      = 0x80000005;
// 2 Hardened leather, thick hide
+
integer LM_ARMORBATTERY  = 0x80000006;
// 3 Chain mail, dragon hide
+
integer LM_ARMORRECHARGE = 0x80000007;
// 4 Full plate mail, mithril chain
+
integer LM_ARMORCHECK    = 0x80000008;
// 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?
+
  
//============================================================================
+
integer MINATTACH = 1; // min valid attach point
// RUNTIME VARIABLES - variables which should change during runtime
+
integer MAXWEAR = 30; // max valid in-world wearable attach point
//============================================================================
+
integer MINARMOR = 1; // min armor defense value
key WEARER = NULL_KEY; // holds UUID of last wearer, so we can send detach message to correct meter
+
integer MAXARMOR = 5; // max armor defense value
integer ATTACHPOINT = 0; // the avatar position where armor attached to or detached from
+
integer CURARMOR = 0; // highest armor value worn out of all armor worn, not a total
integer CHANATTACH; // owner's attachment channel
+
list ARMOR = [];
integer HANDATTACH; // chat handle for attachment channel
+
// string names for each attach point - waste of memory?
integer ARMOR_ON = TRUE; // is armor "on" and protecting?
+
list ATTACHPOINTS = ["INVALID","chest","head","left shoulder","right shoulder","left hand","right hand","left foot","right foot","back","pelvis","mouth","chin","left ear","right ear","left eye","right eye","nose","right upper arm","right lower arm","left upper arm","left lower arm","right hip","right upper leg","right lower leg","left hip","left upper leg","left lower leg","stomach","left pectoral","right pectoral","HUD Center 2","HUD Top Right","HUD Top","HUD Top Left","HUD Center","HUD Bottom Left","HUD Bottom","HUD Bottom Right" ];
integer BATTERY; // current charge left for power armor
+
integer EFFECTTIME; // how much time is left to show armor effects
+
  
//============================================================================
+
string CHAN_PREFIX = "0x"; // channel prefix for calculating dynamic channels
// DEBUG - show debug chat with wearer name for sorting
+
string DIV = "|"; // message field divider
//============================================================================
+
integer CHANATTACH = 0; // dynamic channel for attachments
DEBUG(string dmessage) {
+
    llOwnerSay("DEBUG: "+dmessage);
+
}
+
  
//============================================================================
+
// ERROR - show errors on debug channel with wearer name for sorting
// EFFECTHIT() - SHOW SPECIAL ARMOR EFFECTS WHEN ARMOR HIT BUT FAILS TO BLOCK
+
ERROR(string emessage) {
//============================================================================
+
     llSay(DEBUG_CHANNEL,"ERROR ("+llKey2Name(PLAYERID)+"): "+emessage);
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
+
 
}
 
}
  
//============================================================================
+
// WEARARMOR - Wearing a piece of armor
// EFFECTBLOCKED - CHANGE ARMOR EFFECT WHEN ARMOR HIT AND BLOCKS DAMAGE
+
WEARARMOR(integer waattachpoint,integer waamount,string waname) {
//============================================================================
+
    if ( waattachpoint < MINATTACH || waattachpoint > MAXWEAR ) { // valid attach point?
EFFECTBLOCKED() {
+
        ERROR("Invalid armor attachment point "+llList2String(ATTACHPOINTS,waattachpoint));
     // your commands go here for armor special effect when armor BLOCKS a hit
+
        return;
          
+
     }
     // end of special effects
+
    if ( waamount < MINARMOR || waamount > MAXARMOR ) { // is armor rating valid or legal?
     EFFECTTIME = MAXEFFECTTIME; // load the countdown
+
        ERROR("Invalid armor amount "+(string)waamount+" out of range "+(string)MINARMOR+"-"+(string)MAXARMOR);
 +
         return;
 +
    }
 +
     // FIXME move ARMOR to 3-element strided list? [attachpoint,value,name?]
 +
     ARMOR = llListReplaceList(ARMOR,[waamount],waattachpoint,waattachpoint); // insert armor value into armor list
 +
    llOwnerSay("Armor "+waname+" ("+(string)waamount+") attached to "+llList2String(ATTACHPOINTS,waattachpoint));
 +
    RECALCULATE_ARMOR(); // find new highest armor value
 
}
 
}
  
//============================================================================
+
// REMOVEARMOR - Removing a piece of armor
// EFFECTOFF - RESET ARMOR TO NORMAL VIEW
+
REMOVEARMOR(integer raattachpoint,integer raamount,string raname) {
//============================================================================
+
     if ( raattachpoint < MINATTACH || raattachpoint > MAXWEAR ) { // valid attach point?
EFFECTOFF() {
+
         ERROR("Invalid armor detachment point "+llList2String(ATTACHPOINTS,raattachpoint));
    // 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;
 
         return;
 
     }
 
     }
     if ( BATTERY <= 0 ) {
+
     if ( raamount < MINARMOR || raamount > MAXARMOR ) { // is armor rating valid or legal?
         llOwnerSay("Armor out of power. Recharge.");
+
         ERROR("Invalid armor amount "+(string)raamount+" out of range "+(string)MINARMOR+"-"+(string)MAXARMOR);
 
         return;
 
         return;
 +
    }   
 +
    ARMOR = llListReplaceList(ARMOR,[0],raattachpoint,raattachpoint); // zero out the armor value in armor list
 +
    llOwnerSay("Armor "+raname+" ("+(string)raamount+") detached from "+llList2String(ATTACHPOINTS,raattachpoint));
 +
    RECALCULATE_ARMOR(); // find new highest armor value
 +
}
 +
 +
// RECALCULATE_ARMOR - sets CURARMOR to highest armor value worn after attach or detach
 +
RECALCULATE_ARMOR() {
 +
    CURARMOR = 0; // start with zero armor
 +
    integer racount = llGetListLength(ARMOR); // how long is armor list?
 +
    while (racount--) { // look at each list item from last to first
 +
        integer rapoints = llList2Integer(ARMOR,racount); // what is armor value at this point in list?
 +
        if ( rapoints > CURARMOR ) { // is this armor value higher than current max?
 +
            CURARMOR = rapoints; // yes, save new highest amount
 +
        }
 
     }
 
     }
     ARMOR_ON = TRUE;
+
     llOwnerSay("Armor Rating is "+(string)CURARMOR);
     // your special effect code here
+
     llMessageLinked(LINK_THIS,LM_ARMORCURRENT,"ARMORCURRENT|"+(string)CURARMOR,PLAYERID);
    llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES);
+
     // FIXME tell world too?
     llSetTimerEvent(1.0); // run a battery drain timer, battery already checked > 0
+
 
}
 
}
  
//============================================================================
+
// ARMOR ON
// ARMOR OFF - DEACTIVATE POWERED ARMOR
+
ARMORON() {
//============================================================================
+
    llWhisper(CHANATTACH,"ARMORON");
 +
}
 +
 
 +
// ARMOROFF
 
ARMOROFF() {
 
ARMOROFF() {
     if ( POWERARMOR != TRUE ) {
+
     llWhisper(CHANATTACH,"ARMOROFF");
        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);
+
 
}
 
}
  
//============================================================================
+
// CHECKBATTERY
// CHECK BATTERY
+
//============================================================================
+
 
CHECKBATTERY() {
 
CHECKBATTERY() {
     if ( POWERARMOR != TRUE ) {
+
     llWhisper(CHANATTACH,"CHECKBATTERY");
        llOwnerSay("Cannot check battery level for non-powered armor.");
+
        return;
+
    }
+
    llOwnerSay("Armor battery level: "+(string)BATTERY+" of "+(string)MAXBATTERY+" total.");
+
 
}
 
}
  
//============================================================================
+
// RECHARGE
// RECHARGE POWER ARMOR BATTERY
+
//============================================================================
+
 
RECHARGE() {
 
RECHARGE() {
     if ( POWERARMOR != TRUE ) {
+
     llWhisper(CHANATTACH,"RECHARGE");
        llOwnerSay("Cannot recharge non-powered armor.");
+
        return;
+
    }
+
    // TODO Partial Recharges?
+
    BATTERY = MAXBATTERY;
+
    llOwnerSay("Armor recharged.");
+
 
}
 
}
  
//============================================================================
+
// SETUP - begin
// GLOBAL SETUP()
+
//============================================================================
+
 
SETUP() {
 
SETUP() {
     // calculate a dynamic chat channel based on owner key, for where the
+
     PLAYERID = llGetOwner(); // remember the owner's UUID
     // wearer's ML HUD should be listening of attachment -specific events
+
     integer attachpoints = 37; // counting from 0 to 37
     CHANATTACH = (integer)(CHAN_PREFIX+llGetSubString((string)llGetOwner(),1,7));
+
    while ( attachpoints-- ) {
    // open a channel, listening on player HUD channel, save handle for later close if needed
+
        ARMOR = ARMOR + [0]; // create 38 empty armor slots - avoids SL stack depth error and LSLINT warning
    HANDATTACH = llListen(CHANATTACH,"",NULL_KEY,"");
+
    }
    if ( POWERARMOR == TRUE ) BATTERY = MAXBATTERY; // charge the battery to full
+
     CHANATTACH = (integer)(CHAN_PREFIX+llGetSubString((string)PLAYERID,1,7)); // attachment-specific channel
     llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES); // show the armor
+
}
 +
 
 +
// RESET - shut down running animations then reset the script to reload character sheet
 +
RESET() {
 +
     llResetScript(); // now reset
 
}
 
}
  
//============================================================================
 
// DEFAULT
 
//============================================================================
 
 
default {
 
default {
    //------------------------------------------------------------------------
 
    // DEFAULT STATE ENTRY - begin our setup or call a setup block
 
    //------------------------------------------------------------------------
 
 
     state_entry() {
 
     state_entry() {
         SETUP(); // call the event-independent SETUP code
+
         SETUP();
 
     }
 
     }
     //------------------------------------------------------------------------
+
      
    // DEFAULT ON_REZ
+
     on_rez(integer params) {
    //------------------------------------------------------------------------
+
         params = 0; // LSLINT
     on_rez(integer start_param) {
+
         RESET();
         start_param = 0; // LSLINT
+
         SETUP(); // call event independent SETUP code       
+
 
     }
 
     }
     //------------------------------------------------------------------------
+
      
    // DEFAULT ATTACH - Called for detach too
+
    //------------------------------------------------------------------------
+
 
     attach(key id) {
 
     attach(key id) {
         SETUP(); // call event-independent SETUP code
+
         id = NULL_KEY; // LSLINT
        // is this an attach event or detach event?
+
         RESET();
        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 - triggered for many changes to the avatar
     //------------------------------------------------------------------------
+
     // TODO reload sim-specific settings on region change
     changed(integer change) {
+
     changed(integer changes) {
         if ( change & CHANGED_OWNER ) { // if armor has a new owner from take-from-ground or copy, resetup
+
         if ( changes & CHANGED_INVENTORY ) { // inventory changed somehow?
             SETUP(); // call event-independent setup code, in this case to update channels
+
             RESET();
 
         }
 
         }
         if ( ( change & CHANGED_REGION ) || ( change & CHANGED_TELEPORT ) ) {
+
         if ( changes & CHANGED_REGION || changes & CHANGED_TELEPORT ) {
             EFFECTOFF(); // stop effects before reset
+
             RESET();
            // FIXME - resets battery state
+
            llResetScript(); // restart attachment after region change or teleport
+
 
         }
 
         }
     }  
+
     }
     //------------------------------------------------------------------------
+
     // LINK MESSAGE - commands to and from other prims in HUD
     // DEFAULT LISTEN
+
     link_message(integer sender,integer num,string cmd, key id) {
    //------------------------------------------------------------------------
+
         sender = 0 ; // LSLINT
    listen(integer channel,string speakername,key speakerid,string message) {
+
         id = NULL_KEY; // LSLINT
         speakername = ""; // LSLINT
+
         // break down the commands and messages into units we can work with
         speakerid = NULL_KEY; // LSLINT
+
         list fields = llParseString2List(cmd,[DIV],[]); // break into list of fields based on DIVider
         ATTACHPOINT = llGetAttached(); // get location we're attached to
+
        string command = llToLower(llStringTrim(llList2String(fields,0),STRING_TRIM)); // assume the first field is a Myriad Lite command
         if ( channel == CHANATTACH ) { // is this message on the attach channel?
+
        if ( num == LM_ATTACHARMOR || command == "attacharmor" ) {      
            if ( message == "ARMORHIT" ) { // is this an armor hit?
+
             integer armorrating = llList2Integer(fields,1); // get armor value
                EFFECTHIT(); // turn on armor hit effects
+
             integer attachpoint = llList2Integer(fields,2); // get armor location
                return; // message processed, exit early
+
             string armorname = llList2String(fields,3); // get armor's name
            }
+
             WEARARMOR(attachpoint,armorrating,armorname); // add armor to set of armor worn
            if ( message == "ARMORBLOCKED" ) { // did the armor block the hit too
+
             return;
                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
+
         if ( num == LM_DETACHARMOR || command == "detacharmor" ) {
    } // end timer
+
            integer armorrating = llList2Integer(fields,1); // get armor value
} // end default
+
            integer attachpoint = llList2Integer(fields,2); // get armor location
//============================================================================
+
            string armorname = llList2String(fields,3); // get armor's name
// END
+
            REMOVEARMOR(attachpoint,armorrating,armorname); // detach armor from set of armor worn
//============================================================================
+
            return;
 +
        }
 +
        if ( num == LM_ARMOROFF || command == "armoroff" ) { ARMOROFF(); return;} // turn off power armor
 +
        if ( num == LM_ARMORON || command == "armoron" ) { ARMORON(); return;} // turn on power armor
 +
        if ( num == LM_ARMORCHECK || command == "checkarmor" ) { RECALCULATE_ARMOR(); return; } // check our current armor value
 +
        if ( num == LM_ARMORBATTERY || command == "checkbattery") { CHECKBATTERY(); return;}  // check power armor battery
 +
        if ( num == LM_ARMORRECHARGE || command == "recharge" ) { RECHARGE(); return;} // recharge power armor battery
 +
        if ( num == LM_ARMORRESET || command == "armorreset" ) { RESET(); return;} // reset HUD
 +
    }
 +
}
 
</nowiki>
 
</nowiki>

Revision as of 09:50, 6 February 2012

Myriad Lite Module: Armor

The Myriad Lite Module Armor script (below) goes into the Myriad Lite HUD.

More information such as API messages will be in a later Preview release.

Myriad_Lite_Module_Armor-v0.0.5-20120130.lsl

// Myriad_Lite_Module_Armor-v0.0.0-20120125.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-2012 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.

key PLAYERID = NULL_KEY; // cached player UUID

integer LM_ATTACHARMOR   = 0x80000000;
integer LM_DETACHARMOR   = 0x80000001;
integer LM_ARMORCURRENT  = 0x80000002;
integer LM_ARMORRESET    = 0x80000003;
integer LM_ARMORON       = 0x80000004;
integer LM_ARMOROFF      = 0x80000005;
integer LM_ARMORBATTERY  = 0x80000006;
integer LM_ARMORRECHARGE = 0x80000007;
integer LM_ARMORCHECK    = 0x80000008;

integer MINATTACH = 1; // min valid attach point
integer MAXWEAR = 30; // max valid in-world wearable attach point
integer MINARMOR = 1; // min armor defense value
integer MAXARMOR = 5; // max armor defense value
integer CURARMOR = 0; // highest armor value worn out of all armor worn, not a total
list ARMOR = [];
// string names for each attach point - waste of memory?
list ATTACHPOINTS = ["INVALID","chest","head","left shoulder","right shoulder","left hand","right hand","left foot","right foot","back","pelvis","mouth","chin","left ear","right ear","left eye","right eye","nose","right upper arm","right lower arm","left upper arm","left lower arm","right hip","right upper leg","right lower leg","left hip","left upper leg","left lower leg","stomach","left pectoral","right pectoral","HUD Center 2","HUD Top Right","HUD Top","HUD Top Left","HUD Center","HUD Bottom Left","HUD Bottom","HUD Bottom Right" ];

string CHAN_PREFIX = "0x"; // channel prefix for calculating dynamic channels
string DIV = "|"; // message field divider
integer CHANATTACH = 0; // dynamic channel for attachments

// ERROR - show errors on debug channel with wearer name for sorting
ERROR(string emessage) {
    llSay(DEBUG_CHANNEL,"ERROR ("+llKey2Name(PLAYERID)+"): "+emessage);
}

// WEARARMOR - Wearing a piece of armor
WEARARMOR(integer waattachpoint,integer waamount,string waname) {
    if ( waattachpoint < MINATTACH || waattachpoint > MAXWEAR ) { // valid attach point?
        ERROR("Invalid armor attachment point "+llList2String(ATTACHPOINTS,waattachpoint));
        return;
    }
    if ( waamount < MINARMOR || waamount > MAXARMOR ) { // is armor rating valid or legal?
        ERROR("Invalid armor amount "+(string)waamount+" out of range "+(string)MINARMOR+"-"+(string)MAXARMOR);
        return;
    }
    // FIXME move ARMOR to 3-element strided list? [attachpoint,value,name?]
    ARMOR = llListReplaceList(ARMOR,[waamount],waattachpoint,waattachpoint); // insert armor value into armor list
    llOwnerSay("Armor "+waname+" ("+(string)waamount+") attached to "+llList2String(ATTACHPOINTS,waattachpoint));
    RECALCULATE_ARMOR(); // find new highest armor value
}

// REMOVEARMOR - Removing a piece of armor
REMOVEARMOR(integer raattachpoint,integer raamount,string raname) {
    if ( raattachpoint < MINATTACH || raattachpoint > MAXWEAR ) { // valid attach point?
        ERROR("Invalid armor detachment point "+llList2String(ATTACHPOINTS,raattachpoint));
        return;
    }
    if ( raamount < MINARMOR || raamount > MAXARMOR ) { // is armor rating valid or legal?
        ERROR("Invalid armor amount "+(string)raamount+" out of range "+(string)MINARMOR+"-"+(string)MAXARMOR);
        return;
    }    
    ARMOR = llListReplaceList(ARMOR,[0],raattachpoint,raattachpoint); // zero out the armor value in armor list
    llOwnerSay("Armor "+raname+" ("+(string)raamount+") detached from "+llList2String(ATTACHPOINTS,raattachpoint));
    RECALCULATE_ARMOR(); // find new highest armor value
}

// RECALCULATE_ARMOR - sets CURARMOR to highest armor value worn after attach or detach
RECALCULATE_ARMOR() {
    CURARMOR = 0; // start with zero armor
    integer racount = llGetListLength(ARMOR); // how long is armor list?
    while (racount--) { // look at each list item from last to first
        integer rapoints = llList2Integer(ARMOR,racount); // what is armor value at this point in list?
        if ( rapoints > CURARMOR ) { // is this armor value higher than current max?
            CURARMOR = rapoints; // yes, save new highest amount
        }
    }
    llOwnerSay("Armor Rating is "+(string)CURARMOR);
    llMessageLinked(LINK_THIS,LM_ARMORCURRENT,"ARMORCURRENT|"+(string)CURARMOR,PLAYERID);
    // FIXME tell world too?
}

// ARMOR ON
ARMORON() {
    llWhisper(CHANATTACH,"ARMORON");
}

// ARMOROFF
ARMOROFF() {
    llWhisper(CHANATTACH,"ARMOROFF");
}

// CHECKBATTERY
CHECKBATTERY() {
    llWhisper(CHANATTACH,"CHECKBATTERY");
}

// RECHARGE
RECHARGE() {
    llWhisper(CHANATTACH,"RECHARGE");
}

// SETUP - begin
SETUP() {
    PLAYERID = llGetOwner(); // remember the owner's UUID
    integer attachpoints = 37; // counting from 0 to 37
    while ( attachpoints-- ) {
        ARMOR = ARMOR + [0]; // create 38 empty armor slots - avoids SL stack depth error and LSLINT warning
    }
    CHANATTACH = (integer)(CHAN_PREFIX+llGetSubString((string)PLAYERID,1,7)); // attachment-specific channel
}

// RESET - shut down running animations then reset the script to reload character sheet
RESET() {
    llResetScript(); // now reset
}

default {
    state_entry() {
        SETUP();
    }
    
    on_rez(integer params) {
        params = 0; // LSLINT
        RESET();
    }
    
    attach(key id) {
        id = NULL_KEY; // LSLINT
        RESET();
    }
    
    // CHANGED - triggered for many changes to the avatar
    // TODO reload sim-specific settings on region change
    changed(integer changes) {
        if ( changes & CHANGED_INVENTORY ) { // inventory changed somehow?
            RESET();
        }
        if ( changes & CHANGED_REGION || changes & CHANGED_TELEPORT ) {
            RESET();
        }
    }
    // LINK MESSAGE - commands to and from other prims in HUD
    link_message(integer sender,integer num,string cmd, key id) {
        sender = 0 ; // LSLINT
        id = NULL_KEY; // LSLINT
        // break down the commands and messages into units we can work with
        list fields = llParseString2List(cmd,[DIV],[]); // break into list of fields based on DIVider
        string command = llToLower(llStringTrim(llList2String(fields,0),STRING_TRIM)); // assume the first field is a Myriad Lite command
        if ( num == LM_ATTACHARMOR || command == "attacharmor" ) {        
            integer armorrating = llList2Integer(fields,1); // get armor value
            integer attachpoint = llList2Integer(fields,2); // get armor location
            string armorname = llList2String(fields,3); // get armor's name
            WEARARMOR(attachpoint,armorrating,armorname); // add armor to set of armor worn
            return;
        }
        if ( num == LM_DETACHARMOR || command == "detacharmor" ) {
            integer armorrating = llList2Integer(fields,1); // get armor value
            integer attachpoint = llList2Integer(fields,2); // get armor location
            string armorname = llList2String(fields,3); // get armor's name
            REMOVEARMOR(attachpoint,armorrating,armorname); // detach armor from set of armor worn
            return;
        }
        if ( num == LM_ARMOROFF || command == "armoroff" ) { ARMOROFF(); return;} // turn off power armor
        if ( num == LM_ARMORON || command == "armoron" ) { ARMORON(); return;} // turn on power armor
        if ( num == LM_ARMORCHECK || command == "checkarmor" ) { RECALCULATE_ARMOR(); return; } // check our current armor value
        if ( num == LM_ARMORBATTERY || command == "checkbattery") { CHECKBATTERY(); return;}  // check power armor battery
        if ( num == LM_ARMORRECHARGE || command == "recharge" ) { RECHARGE(); return;} // recharge power armor battery
        if ( num == LM_ARMORRESET || command == "armorreset" ) { RESET(); return;} // reset HUD
    }
}

Personal tools
General
About This Wiki