User:Allen Kerensky/Myriad Lite Preview 5/Module Armor
From OpenSimulator
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
- 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
//============================================================================ // 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 //============================================================================