User:Allen Kerensky/Myriad Lite Preview 5/Melee

= Myriad Lite Melee =

Melee weapons are hand-held weapons that strike opponents directly around you, as opposed to a ranged weapon like a firearm or bow.

Melee Attack Dice
The Myriad RPG System includes these reference melee weapon attack/damage suggestions:
 * 1) Unarmed Combat
 * 2) Short animal claws, knife, dagger, blackjack, knuckledusters
 * 3) Long animal claws, short sword, machete, wooden baseball bat, staff
 * 4) Fire axe, long sword, katana, aluminum baseball bat, poleaxe
 * 5) Battleaxe, claymore, laser sword, daikatana, double-ended polearm

Setup

 * 1) Create a melee object, such as a sword approximately 1m long.
 * 2) Drag and Drop the Myriad Lite Melee script for sword fighting (below) from inventory into the object
 * 3) Take the melee weapon into into inventory.
 * 4) Attach it to your right hand
 * 5) Adjust the position and rotation
 * 6) Detach the mele weapon back into inventory again to "save" the new default attach point.
 * 7) Attach or wear the melee weapon when desired.

Myriad_Lite_Melee-v0.0.4-20120202.lsl
//============================================================================ // Myriad_Lite_Melee-v0.0.4-20120202.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 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 // 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) { params = 0; // LSLINT 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) { speakername = ""; // LSLINT speakerid = NULL_KEY; // LSLINT 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 //============================================================================