Myriad_Lite_Armor-v0.0.6-20120212.lsl
//============================================================================
// Myriad_Lite_Armor_v0.0.6-20120212.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
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
//============================================================================