User:Allen Kerensky/Myriad Lite Preview4/Myriad Lite Melee v0.0.3 20110903

From Second Life Wiki
< User:Allen Kerensky
Revision as of 07:35, 8 September 2011 by Allen Kerensky (talk | contribs) (created)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Myriad Lite Melee v0.0.3 20110903

<lsl> //============================================================================ // Myriad Lite Melee v0.0.3 20110903 // Copyright (c) 2011 By Allen Kerensky (OSG/SL) // The Myriad RPG System was designed, written, and illustrated by Ashok Desai // Myriad published under a: // Creative Commons License (Attribution 2.0 UK: England and Wales) // Myriad Lite published under a // Creative Commons License Attribution-NonCommercial-ShareAlike 3.0 Unported //============================================================================

//============================================================================ // MESSAGE FORMAT REFERENCE //============================================================================ // CHANMYRIAD OUT - RPEVENT|message // CHANATTACH IN - REGISTERATTACHMENTS // CHANATTACH OUT - ATTACHMELEE|int attackdice|int attachpoint|str name // CHANATTACH OUT - DETACHMELEE|int attackdice|int attachpoint|str name // CHANPLAYER OUT - CLOSECOMBAT|int attackdice|key victim|key attacker|str weaponname

//============================================================================ // GLOBAL VARIABLES //============================================================================ key WEARER = NULL_KEY; // UUID of melee weapon user integer ATTACHPOINT = 0; // attachment point integer MINMELEE = 1; // minimum attack dice for melee weapons integer MAXMELEE = 5; // maximum attack dice for melee weapons // Melee Attack Dice // 1D - Unarmed Combat // 2D - Short animal claws, knife, dagger, blackjack, knuckledusters // 3D - Long animal claws, short sword, machete, wooden baseball bat, staff // 4D - Fire axe, long sword, katana, aluminum baseball bat, poleaxe // 5D - Battleaxe, claymore, laser sword, daikatana, double-ended polearm integer MELEEATTACKDICE = 4; // long sword string DIV="|"; // Myriad message field divider string ANIM_SWORD = "sword_strike_r"; // use built in right handed sword strike animation integer CHANATTACH; // hold the dynamically calculated attachment channel number integer HANDATTACH; // hold a handle to remove the attachment channel if needed integer CHANMYRIAD = -999; // the Myriad RPEVENT channel number integer ANIM = FALSE; // do we have permission to animate the avatar? float WEAPON_LENGTH = 2.0; // a six-foot longsword is the default integer SAFETY_ON = TRUE; // can this weapon be used or is it sheathed?

// SAFETY OFF - turn off safety and enable firing SAFETYOFF() {

   SAFETY_ON = FALSE; // switch the safety off
   llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION); // request permissions

}

// SAFETY ON - turn on safety SAFETYON() {

   SAFETY_ON = TRUE; // switch the safety on
   llReleaseControls();

}

// DRAW THE WEAPON DRAW(string hand) {

   // draw code goes here - turn copy in hand visible?
   if ( llGetAttached() == 5 && ( hand == "left" || hand == "both" ) ) {
       llRegionSay(CHANMYRIAD,llKey2Name(llGetOwner())+" draws a weapon with their left hand.");
       llOwnerSay("Left hand weapon drawn.");
       llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES);        
   }
   if ( llGetAttached() == 6 && ( hand == "right" || hand == "both" ) ) {
       llRegionSay(CHANMYRIAD,llKey2Name(llGetOwner())+" draws a weapon with their right hand.");
       llOwnerSay("Right hand weapon drawn.");
       llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES);        
   }
   SAFETYOFF(); // unholster and turn off safety

}

// SHEATHE THE WEAPON SHEATHE(string hand) {

   // sheathe code goes here - turn copy in hand invisible?
   if ( llGetAttached() == 5 && ( hand == "left" || hand == "both" ) ) {
       llRegionSay(CHANMYRIAD,llKey2Name(llGetOwner())+" sheathes their left-hand weapon.");
       llOwnerSay("Left hand weapon sheathed.");
       llSetLinkAlpha(LINK_SET,0.0,ALL_SIDES);        
   }
   if ( llGetAttached() == 6 && ( hand == "right" || hand == "both" ) ) {
       llRegionSay(CHANMYRIAD,llKey2Name(llGetOwner())+" sheathes their right-hand weapon.");
       llOwnerSay("Right hand weapon sheathed.");
       llSetLinkAlpha(LINK_SET,0.0,ALL_SIDES);        
   }
   SAFETYON(); // turn on safety before holstering

}

// SETUP THE WEAPON SETUP() {

   CHANATTACH = (integer)("0x"+llGetSubString((string)llGetOwner(),1,7)); // calculate dynamic attachment channel
   HANDATTACH = llListen(CHANATTACH,"",NULL_KEY,""); // start listening on attachment channel
   SAFETY_ON = TRUE; // safe the weapon until drawn
   llSetLinkAlpha(LINK_SET,0.0,ALL_SIDES); // turn invisble as if sheathed

}

//============================================================================ // DEFAULT STATE //============================================================================ default {

   //------------------------------------------------------------------------
   // STATE_ENTRY EVENT - called on reset
   //------------------------------------------------------------------------    
   state_entry() {
       SETUP();
   }
   //------------------------------------------------------------------------
   // ON_REZ EVENT
   //------------------------------------------------------------------------
   on_rez(integer params) {
       SETUP();
   }
   
   //------------------------------------------------------------------------
   // ATTACH EVENT
   //------------------------------------------------------------------------
   attach(key id) {
       if ( id != NULL_KEY ) { // if id not equal null key, this is an attach
           WEARER = id; // save the id we attached to
           ATTACHPOINT = llGetAttached(); // get the position we attached to
           // tell the region we're arming a weapon
           llRegionSay(CHANMYRIAD,"RPEVENT"+DIV+llKey2Name(WEARER)+" equips their "+llGetObjectName());
           integer dynchan = (integer)("0x"+llGetSubString((string)WEARER,1,7)); // calculate dynamic attach channel
           // send attach melee message to HUD which disables fist fighter
           llWhisper(dynchan,"ATTACHMELEE"+DIV+(string)MELEEATTACKDICE+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
           llRequestPermissions(id,PERMISSION_TAKE_CONTROLS|PERMISSION_TRIGGER_ANIMATION); // request permissions
       } else { // the id was null key, so this is a detach
           integer dynchan = (integer)("0x"+llGetSubString((string)WEARER,1,7)); // calculate dynamic attach channel
           if ( dynchan != 0 ) { // is channel valid
               // tell the region we're disarming
               llRegionSay(CHANMYRIAD,"RPEVENT"+DIV+llKey2Name(WEARER)+" disarms their "+llGetObjectName());
               // send detach message to HUD which re-enables fist fighter
               llWhisper(dynchan,"DETACHMELEE"+DIV+(string)MELEEATTACKDICE+DIV+(string)ATTACHPOINT+DIV+llGetObjectName());
           } else { // channel was not valid
               llSay(DEBUG_CHANNEL,"DETACH EVENT WITHOUT PREVIOUS ATTACH?"); // report the problem
           }
           WEARER = NULL_KEY; // cleanup wearer key on detach
           ATTACHPOINT = 0; // cleanup attachpoint on detach
       }
   }
   //------------------------------------------------------------------------
   // LISTEN EVENT - whisper, say, show, regionsay...
   //------------------------------------------------------------------------    
   listen(integer channel,string speakername,key speakerid,string message) {
       if ( channel == CHANATTACH ) { // did this message come in on attachment channel?
           if ( message == "REGISTERATTACHMENTS" ) { // is this a HUD asking for attachments to register?
               WEARER = llGetOwner(); // who is wielding me?
               ATTACHPOINT = llGetAttached(); // where am I attached?
               integer dynchan = (integer)("0x"+llGetSubString((string)WEARER,1,7)); // calculate wearer's dynamic attachment channel
               llWhisper(dynchan,"ATTACHMELEE"+DIV+(string)MELEEATTACKDICE+DIV+(string)ATTACHPOINT+DIV+llGetObjectName()); // tell HUD we're attached to disable fist fighter
               return;
           }
           if ( message == "DRAWLEFT" ) { DRAW("left"); return;} // draw weapon if in left hand
           if ( message == "DRAWRIGHT" ) { DRAW("right"); return;} // draw weapon in right hand
           if ( message == "DRAWBOTH" ) { DRAW("both"); return; } // draw weapon in both hands
           if ( message == "SHEATHELEFT" ) { SHEATHE("left"); return;} // sheathe left-hand weapon
           if ( message == "SHEATHERIGHT" ) { SHEATHE("right"); return;} // sheathe right-hand weapon
           if ( message == "SHEATHEBOTH" ) { SHEATHE("both"); return; } // sheathe both weapon
           if ( message == "SAFETYOFF" ) { SAFETYOFF(); return; } // unsafe the weapon
           if ( message == "SAFETYON" ) { SAFETYON(); return; } // safe the weapon
       }
   }
   //------------------------------------------------------------------------
   // RUN_TIME_PERMISSIONS EVENT - what is object allowed to do to avatar?
   //------------------------------------------------------------------------    
   run_time_permissions(integer perm) {
       if ( perm & PERMISSION_TAKE_CONTROLS ) { // can object read controls?
           llTakeControls(CONTROL_LBUTTON|CONTROL_ML_LBUTTON,TRUE,TRUE); // start watching the left mouse button in both views
       }
       if ( perm & PERMISSION_TRIGGER_ANIMATION ) { // can we also trigger animations for sword swings?
           ANIM = TRUE; // remember that we have permission now
       }
   }
   //------------------------------------------------------------------------
   // CONTROL EVENT - read arrow keys and mouse button
   //------------------------------------------------------------------------    
   control(key id,integer level,integer edge) {
       if ( SAFETY_ON == TRUE ) {
           llOwnerSay("Your weapon is sheathed, draw it!");
           llReleaseControls();
           return;
       }
       if ( id == WEARER ) { // make sure controls come from wielder
           if ( ( level & CONTROL_LBUTTON && edge & CONTROL_LBUTTON ) || ( level & CONTROL_ML_LBUTTON && edge & CONTROL_ML_LBUTTON ) ) { // if left mouse button pressed in regular or mouselook mode
               llSensor("",NULL_KEY,(AGENT|ACTIVE|PASSIVE),WEAPON_LENGTH,PI/6); // trigger a sensor sweep for avatars within weapon range, and standing in front of us
               if ( ANIM == TRUE ) llStartAnimation(ANIM_SWORD); // if we can show sword swing, go ahead
               llSleep(0.2); // pause to let animation run
               return; // return now to skip processing any more events we add later
           }
       }
   }
   //------------------------------------------------------------------------
   // SENSOR EVENT - what did we find?
   //------------------------------------------------------------------------    
   sensor(integer num_detected) {
       while(num_detected--) { // step through all AGENTS returned by sensor sweep
           integer dynchan = (integer)("0x"+llGetSubString((string)llGetOwner(),0,6)); // calculate attackers HUD dynamic channel
           // send the close combat skill check message to attacker to start close combat skill check
           // attackers hud adds attacker stat and skill and sends the information to the victim to finish the opposed close combat skill check
           // we region say this so others can keep score or detect cheaters, etc
           llRegionSay(dynchan,"CLOSECOMBAT"+DIV+(string)MELEEATTACKDICE+DIV+(string)llDetectedKey(num_detected)+DIV+(string)llGetOwner()+DIV+llGetObjectName());
           
           key who = llDetectedKey(num_detected); // who did we hit with sensor?
           key owner = llList2Key(llGetObjectDetails(who,[OBJECT_OWNER]),0); // is this an agent/avatar for sure?
           if ( who == owner ) { // yep, we hit an avatar
               // tell the region an attempted attack is underway
               llRegionSay(CHANMYRIAD,"RPEVENT"+DIV+llKey2Name(llGetOwner())+" strikes at "+llDetectedName(num_detected)+" in Close Combat!");
           }
       }
   }
   //------------------------------------------------------------------------
   // NO_SENSOR EVENT - we didn't find anything to hit
   //------------------------------------------------------------------------    
   no_sensor() {
       // we do nothing in this - but having a nosensor block avoids bugs where sensors would fail if nonsensor was missing
   }

} // end default //============================================================================ // END //============================================================================ </lsl>