User:Allen Kerensky/Myriad Lite Preview 5/Firearm

From OpenSimulator

< User:Allen Kerensky | Myriad Lite Preview 5
Revision as of 08:56, 6 February 2012 by Allen Kerensky (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Myriad Lite Firearm

Many existing firearms can be adapted to fire Myriad Lite bullets.

The main change needed is to add the bullet's damage class as a starting parameter in the llRezObject call which launches the bullet.

Setup

  1. Create a firearm such as a pistol or rifle.
  2. Drag Drop the Firearm script from inventory into the firearm
  3. Drag and Drop in a gunshot sound.
  4. Drag and Drop the Myriad Lite Bullet you made into the firearm.
  5. Edit the Firearm script to have the correct gunshot sound name.
  6. Edit the Firearm script to have the correct bullet object name.
  7. Take the firearm into inventory.
  8. Attach it to your right hand
  9. Adjust the position and rotation.
  10. Detach the firearm back into inventory again to "save" the new default attach point.
  11. Attach or wear the firearm when desired.

Myriad_Lite_Firearm-v1.5-20120130.lsl

//============================================================================
// Myriad_Lite_Firearm-v1.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-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.
//----------------------------------------------------------------------------
// Based on phillip linden (SL) gunscript
// With many refinements by Rhonin Nissondorf (SL)
// Retrieved 2011-04-30 from http://wiki.secondlife.com/wiki/Gun_Script
// Copyright (c) 2009 Linden Research, Inc.
// Licensed under Creative Commons Attribution-Share Alike 3.0 (CC-BY-SA 3.0)
// Converted to OSSL by Allen Kerensky (SL/OSG).
//===========================================================================

//===========================================================================
// MESSAGE FORMAT REFERENCE
//===========================================================================
// CHANMYRIAD OUT - RPEVENT|str event_message
// CHANATTACH IN - REGISTERATTACHMENTS
// CHANATTACH OUT - ATTACHRANGED|int damagedice|int attachpoint|str attachmentname
// CHANATTACH OUT - DETACHRANGED|int damagedice|int attachpoint|str attachmentname

//===========================================================================
// GLOBAL VARIABLES - variables to be changed  below.
//===========================================================================
float BULLET_VELOCITY = 30.0;                       // change this to change the speed of the bullet.
float REPEAT_DELAY = 0.20;                          // delay between bullets, i recommend you dont' set it to  low.
string gunsound = "pistol_shot.wav";                            // string; name of sound in inventory
string ammo =  "Myriad Lite Bullet v0.0.3 20110813"; //name of desired object to be shot out. Must be in the inventory of the "gun".
integer ATTACH_HAND = 6;                            // left hand = 5, right hand = 6
string SAFETY_OFF_MESSAGE = "The safety is now OFF."; //message when you touch it.
string SAFETY_ON_MESSAGE = "The safety is now ON.";        // a message when you... 
string NOT_OWNER = "You are not the owner of this weapon."; //message when non-owner touches it - assumes a sci-fi-like grip with owner ID
string ANIM_HOLD = "hold_R_handgun";                // animation to use when holding pistol
string ANIM_AIM  = "PistolRightSteady1";            // animation to use when aiming in mouselook
float  TIMER_RES = 0.5;                             // time in seconds to check for mouselook to start aim animation, like an AO
integer AVSTATE  = 0;                               // is av in mouselook?
vector OFFSET = <1.10, -0.25, 0.75>;                // rez offset for bullet
vector OFFSET_LEFT  = <1.10,  0.25, 0.75>;                // rez offset for bullet
vector OFFSET_RIGHT = <1.10, -0.25, 0.75>;                // rez offset for bullet
integer CHANMYRIAD = -999;                      // regionwide RPEVENT channel for Myriad
string DIV = "|";                               // field divider between parts of Myriad messages
// Myriad Ranged Weapons Damage Dice, PDF page 64, Myriad Special Edition page 98
// 1 die of damage = small stones thrown by hand (or in crude sling)
// 2 die of damage = throwing knife, derringer, hand catapult, thrown house brick
// 3 die of damage = throwing axe, pistol, hunting rifle, automatic pistol (full auto)
// 4 die of damage = very heavy pistol (Magnum), assault rifle (full auto), shotgun
// 5 die of damage = high velocity sniper rifle, heavy calibre machine gun (full auto)
integer DAMAGEDICE = 3;                             // many damage dice does this bullet do in Myriad? default to pistol here
integer MAXAMMO = 30; // 30 round clip

//===========================================================================
// GLOBAL RUNTIMES - runtime variables we change as we go
// Don't alter anything below if your not  familiar with it.
//===========================================================================
integer SAFETY_ON = TRUE;  // is this weapon safety on or off by default?
vector pos;         // holds our current position temporarily  
rotation rot;       // holds our current rotation temporarily
vector offset;      // holds an offset to where to rez the bullet based on position and rotation   
integer CHANATTACH = 0; // dynamic channel for attachment messages
integer HANDATTACH = 0; // chat channel handle for attachment dynamic channel
integer AMMOLEFT; // how much ammo is left?

//===========================================================================
// GLOBAL SETUP
//===========================================================================
SETUP() {
    CHANATTACH = (integer)("0x"+llGetSubString((string)llGetOwner(),1,7)); // calculate the dynamic attachment channel
    HANDATTACH = llListen(CHANATTACH,"",NULL_KEY,""); // start a listener on the attachment channel
    llWhisper(CHANATTACH,"ATTACHRANGED"+DIV+(string)DAMAGEDICE+DIV+(string)llGetAttached()+DIV+llGetObjectName()); // inform the player HUD that we're using a weapon to turn off fist fighter
    llOwnerSay("Attach me to your right hand, and enter mouselook to fire!");    
    // ask for permission to trigger animations, take controls, and attach to avatar
    llRequestPermissions(llGetOwner(),PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS|PERMISSION_ATTACH);
    llPreloadSound(gunsound); // try pre-loading the gunsound for everyone around
    if ( SAFETY_ON == TRUE ) { // lets tell owner the state of the safety
        if ( llGetAttached() == 5 ) HOLSTER("left"); // safety on? start holstered
        if ( llGetAttached() == 6 ) HOLSTER("right"); // safety on? start holstered
    } else { // safety is not on
        if ( llGetAttached() == 5 ) DRAW("left"); // safety off! start drawn
        if ( llGetAttached() == 6 ) DRAW("right"); // safety off! start drawn
    }
    RELOAD(); // start the weapon with a full clip
    llSetTimerEvent(TIMER_RES); // start a timer running to check for mouselook and start aim animations or not
}

// SAFETY OFF - turn off safety and enable firing
SAFETYOFF() {
    SAFETY_ON = FALSE; // switch the safety off
    llOwnerSay(SAFETY_OFF_MESSAGE); // and tell them
}

// SAFETY ON - turn on safety
SAFETYON() {
    SAFETY_ON = TRUE; // switch the safety on
    llOwnerSay(SAFETY_ON_MESSAGE); // and tell them    
}

// 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
}

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

// RELOAD THE WEAPON
RELOAD() {
    AMMOLEFT = MAXAMMO;
}

// CHECK AMMO LEFT
CHECKAMMO() {
    if ( AMMOLEFT > MAXAMMO ) { AMMOLEFT = MAXAMMO; } // don't overflow clip
    if ( AMMOLEFT < 0 ) { AMMOLEFT = 0; } // can't have negative bullets
    llOwnerSay("Ammo remaining: "+(string)AMMOLEFT);
}

//===========================================================================
// STATE DEFAULT - the main state is the default state.
// When a script is compiled, reset or loaded, this is the state it enters by default.
//===========================================================================
default {
    //-----------------------------------------------------------------------
    // STATE_ENTRY EVENT - Triggered on any state transition and start up
    //-----------------------------------------------------------------------
    state_entry() {
        SETUP(); // call global setup
    }
 
    //-----------------------------------------------------------------------
    // ON_REZ EVENT - Triggered when object attached or rezzed on the ground
    //-----------------------------------------------------------------------
    on_rez(integer rezparams) {
        rezparams = 0; // LSLINT
        SETUP();
    }

    //-----------------------------------------------------------------------
    // ATTACH EVENT - when the object is attached or detached
    //-----------------------------------------------------------------------
    attach(key id) {
        if ( id == NULL_KEY) { // if id is null key, this is a detach event
            llRegionSay(CHANMYRIAD,"RPEVENT"+DIV+llKey2Name(llGetOwner())+ " puts away their "+llGetObjectName());
            llWhisper(CHANATTACH,"DETACHRANGED"+DIV+(string)DAMAGEDICE+DIV+(string)llGetAttached()+DIV+llGetObjectName()); // inform the player HUD that we're using a weapon to turn on fist fighter
            integer perms = llGetPermissions(); // what permissions does object have
            if ( perms & PERMISSION_TRIGGER_ANIMATION ) { // if object has permission to change animations
                llStopAnimation(ANIM_HOLD); // stop the 'hold a weapon' animation since we're detaching
            }
            return;
        }
    }

    //-----------------------------------------------------------------------
    // RUN_TIME_PERMISSIONS EVENT - triggered when avatar grants permissions to object
    // some permissions automatically granted on attach or sit - but you should STILL check correctly for those
    //-----------------------------------------------------------------------
    run_time_permissions(integer perm) {
        if ( perm & PERMISSION_TAKE_CONTROLS ) { // was object granted permission to read control events?
            llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE); // start reading the left mouse button in mouselook mode
        }
        if ( perm & PERMISSION_TRIGGER_ANIMATION ) { // was object granted permission to trigger animations?
            llStartAnimation(ANIM_HOLD); // start the 'hold a weapon' animation
        }
    }
 
    //-----------------------------------------------------------------------
    // TOUCH_START EVENT - trigger at the start of someone clicking on the object
    //-----------------------------------------------------------------------
    touch_start(integer touches) {  // Triggered by the start of agent clicking on object
        while (touches--) { // count down through each touch event
            key who = llDetectedKey(touches); // get the key of who triggered the touch
            if ( llGetOwner() != who ) { // if not the owner
                llInstantMessage(who,NOT_OWNER); // tell them
            } if ( SAFETY_ON == TRUE ) { // lets tell owner the state of the safety
                SAFETY_ON = FALSE;
                if ( llGetAttached() == 5 ) DRAW("left"); // safety off! start drawn
                if ( llGetAttached() == 6 ) DRAW("right"); // safety off! start drawn
            } else if (SAFETY_ON == FALSE ) { // safety is not on
                SAFETY_ON = TRUE;
                if ( llGetAttached() == 5 ) HOLSTER("left"); // safety on? start holstered
                if ( llGetAttached() == 6 ) HOLSTER("right"); // safety on? start holstered
            }
        } // end while
    }
 
    //-----------------------------------------------------------------------
    // CHANGED EVENT - various changes to object can trigger this event
    //-----------------------------------------------------------------------
    changed(integer change) {
        if(change & CHANGED_OWNER) { // did the object change owner through a give or drop/take?
            integer perms = llGetPermissions(); // what permissions does object have?
            if ( perms & PERMISSION_TRIGGER_ANIMATION ) { // if object has permission to change animations
                llStopAnimation(ANIM_HOLD); // stop the 'hold a weapon' animation'
            }
            llResetScript(); // and reset the entire script
        }
    }

    //-----------------------------------------------------------------------
    // EVENT CONTROL - called for user input we've requested with LLTAKECONTROLS
    //-----------------------------------------------------------------------
    control(key owner, integer level, integer edge) {
        owner = NULL_KEY; // LSLINT
        if ( SAFETY_ON == TRUE ) { // check the safety before shooting
            llOwnerSay("The safety is ON."); // warn owner they are shooting with safety on
            return; // return now to prevent running the rest of the shooting code
        }
        integer pressed = level & edge; // level is when you click ,edge would be if you let up.
        if ( pressed & CONTROL_ML_LBUTTON ) { // if left mouse button was pressed in MouseLook mode
            if ( AMMOLEFT <= 0 ) { 
                llOwnerSay("Out of ammo! Reload!");
                return;
            }
            // Fire 1 bullet,,  the heart of the firearm script.
            pos = llGetPos(); // get our current position
            rot = llGetRot(); // get our current rotation
            offset = OFFSET; // start with the base offset for the gun held in the right hand
            if ( ATTACH_HAND == 5 ) { // is weapon in left hand?
                offset = OFFSET_LEFT; // use the left-hand offset
            }
            if ( ATTACH_HAND == 6 ) { // is weapon in right hand?
                offset = OFFSET_RIGHT; // use the right hand offset
            }
            offset *= rot; // now, rotate the offset to match the avatar rotation
            pos += offset; // now combine the rotated offset with avatar position 
            vector fwd = llRot2Fwd(rot); // calculate the direction that is "avatar's facing" 
            fwd *= BULLET_VELOCITY; // now multiply that by bullet speed to tell bullet to push in that direction, that fast
            rot *= llEuler2Rot(<0, PI_BY_TWO, 0>); // now, straighten rotation for object we're about to rez
            llPlaySound(gunsound,1.0); // here "gunsound"is a variable defined above.
            // DAMAGEDICE is passed to rez-param of bullet. Myriad Bullets read this as damage dice to do if they hit
            AMMOLEFT--;
            llRezObject(ammo, pos, fwd, rot, DAMAGEDICE); // does the actual work rezzes the ammo in the specified variables.
            llSleep(REPEAT_DELAY); // force a pause between shots
        }
    }

    //-----------------------------------------------------------------------
    // LISTEN EVENT - listen for whisper, say, shout, regionsay messages
    //-----------------------------------------------------------------------
    listen(integer channel, string name, key uuid, string message) {
        name = ""; // LSLINT
        uuid = NULL_KEY; // LSLINT
        if ( channel == CHANATTACH ) { // did message come in on attachment channel?
            if ( message == "REGISTERATTACHMENTS" ) { // request from a HUD to register attachments already in use
                llWhisper(CHANATTACH,"ATTACHRANGED"+DIV+(string)DAMAGEDICE+DIV+(string)llGetAttached()+DIV+llGetObjectName()); // inform the player HUD that we're using a weapon to turn off fist fighter
                return;
            }
            if ( message == "DRAWLEFT" ) { DRAW("left"); return;} // draw pistol if in left hand
            if ( message == "DRAWRIGHT" ) { DRAW("right"); return;} // draw pistol in right hand
            if ( message == "DRAWBOTH" ) { DRAW("both"); return; } // draw pistols in both hands
            if ( message == "HOLSTERLEFT" ) { HOLSTER("left"); return;} // holster left-hand pistol
            if ( message == "HOLSTERRIGHT" ) { HOLSTER("right"); return;} // holster right-hand pistol
            if ( message == "HOLSTERBOTH" ) { HOLSTER("both"); return; } // holster both pistols
            if ( message == "SAFETYOFF" ) { SAFETYOFF(); return; } // unsafe the weapon
            if ( message == "SAFETYON" ) { SAFETYON(); return; } // safe the weapon
            if ( message == "CHECKAMMO" ) { CHECKAMMO(); return; } // check ammo left
            if ( message == "RELOAD" ) { RELOAD(); return; } // reload the clip            
        }
    }
    
    //-----------------------------------------------------------------------
    // TIMER EVENT - called regularly as an animation override for holding or aiming weapon
    //-----------------------------------------------------------------------
    timer() {
        if ( SAFETY_ON == TRUE ) return; // if safety is on, don't need to do weapon hold and aim animation
        AVSTATE = llGetAgentInfo(llGetOwner()); // get an integer that holds the current state of the avatar to see if they are in mouselook or not
        if ( AVSTATE & 0x0008 ) { // 0x0008 = AGENT_MOUSELOOK constant - this hack needed on OpenSim
            llStopAnimation(ANIM_HOLD); // stop the 'just hold a weapon' animation
            llSleep(0.05); // wait a little
            llStartAnimation(ANIM_AIM); // start the aiming weapon animation
        } else { // avatar is not in mouselook
            llStopAnimation(ANIM_AIM); // stop the aiming animation
            llSleep(0.05); // wait a little
            llStartAnimation(ANIM_HOLD); // now start the just holding a weapon animation
        }
        AVSTATE = 0; // clean up or reset the avatar state variable
    }
} // end of default
//============================================================================
// END
//============================================================================

Personal tools
General
About This Wiki